A hub on GitHub¶
github.com, GHE.com or GitHub Enterprise Server 3.19 and newer. The hub runs its CI on GitHub Actions with the touchmark Action; a reader App plans on pull requests and a writer App delivers from the default branch.
your-org/engineering-assets the hub: packs/, hub.yml, targets.yml
│ one pull request per repository on every change to a pack
▼
your-org/billing, your-org/sdk-python opted in, or subscribed by the hub
touchmark setup github, run from a clone of the hub with an administrator's token,
does most of steps 2 to 4: it creates both Apps, the environment and the ruleset, and
prints the commands that store the keys. You install the Apps. See
Set up a hub's platform.
Steps¶
- Create the hub. Click Use this template on
the template and
create
your-org/engineering-assets. It can be private, but see the note on GitHub Free below. Don't fork: forks of public repositories are always public. - Create two GitHub Apps in your organisation, and install both on the repositories
you will target, not on the hub:
- reader, with Metadata, Contents and Pull requests read-only;
- writer, with Metadata read-only, and Contents, Pull requests and Workflows read and write. touchmark asks for Workflows only for a target that needs it.
-
Store the keys.
- Reader: the repository variable
TOUCHMARK_READ_APP_ID(the App ID) and the repository secretTOUCHMARK_READ_APP_KEY(its private key). - Writer: create an environment named
touchmark-distribute. Set its Deployment branches and tags to Selected branches and tags, with your default branch only. Store the variableTOUCHMARK_WRITE_APP_IDand the secretTOUCHMARK_WRITE_APP_KEYin that environment, and nowhere else. Don't choose Protected branches only: with no protection rules, every branch qualifies.
The workflow's
probejob stopsdistributeif the write key is also visible as a repository or organisation secret, and touchmark itself checks the environment's branch policy before it writes. 4. Protect the hub. Add a ruleset for the default branch that requires a pull request with an approving review and a review from Code Owners. Replace@acme/hub-maintainersin.github/CODEOWNERSwith your team. 5. Describe your hub. Inhub.ymlsetid, andwriterto the writer App's bot name, likeacme-assets-write[bot]. List your repositories intargets.yml. 6. Open a pull request. Thecheckjob validates the hub; theplanjob reports what each repository would receive and keeps the report in a comment. Write access is checked whendistributeruns, and every week bydoctor. 7. Merge it. Thedistributejob opens a pull request in every repository that has opted in. It runs again every day and on every merge; Run workflow runsdistributeanddoctorat once. The workflow starts on pushes tomainandmaster: if your default branch has another name, add it underpush: branches:. - Reader: the repository variable
What the workflow does¶
| Event | Jobs |
|---|---|
| pull request to the hub | check; plan --strict --comment after an inline probe |
| push to the default branch, every day, Run workflow | probe, then distribute |
| every Monday, Run workflow | probe, then doctor |
Pull requests from Dependabot and from forks get no Actions secrets, so their plan runs
without the read key: it shows the hub's side only, warns that no target was checked, and
passes. Before you merge an engine update, read its release notes and run plan with the
read key yourself.
Notes¶
- GitHub Free. A private hub on GitHub Free cannot limit an environment secret to a
branch, so the isolation check fails. Make the hub public, use the Team plan, or keep
the write key in an external secret store released through OIDC
(
security.write_isolation: external). - Public hubs skip private and internal targets and print only how many: their CI logs are public. See the security model.
- Scheduled workflows in a public repository are disabled by GitHub after 60 days without activity. Push to the hub or re-enable the workflow if the daily run stops.
- GitHub Enterprise Server: use
actions/upload-artifactv3.2.2 in the workflow; v4 and later do not support it. Signed commits through the API need web commit signing turned on by an administrator.
Next: opt a repository in.