|
| 1 | +<!-- |
| 2 | +SPDX-FileCopyrightText: 2026 LibreCode coop and contributors |
| 3 | +SPDX-License-Identifier: AGPL-3.0-or-later |
| 4 | +--> |
| 5 | + |
| 6 | +# Cross-repository automation |
| 7 | + |
| 8 | +LibreCode cross-repository workflow automation is authenticated through the |
| 9 | +**LibreCode Workflow Automation** GitHub App. |
| 10 | + |
| 11 | +## Installation |
| 12 | + |
| 13 | +The App is installed on the `LibreCodeCoop` organization with access to all |
| 14 | +repositories. |
| 15 | + |
| 16 | +The installation-level access is intentionally broad so newly created LibreCode |
| 17 | +repositories do not require a manual App reconfiguration before they can be |
| 18 | +onboarded. |
| 19 | + |
| 20 | +Actual automation remains opt-in: |
| 21 | + |
| 22 | +- catalog publication targets only `LibreCodeCoop/.github`; |
| 23 | +- consumer synchronization targets only repositories declared in |
| 24 | + `consumers.json`; |
| 25 | +- catalog entries are limited by `workflow-catalog.json`. |
| 26 | + |
| 27 | +## GitHub App permissions |
| 28 | + |
| 29 | +Repository permissions: |
| 30 | + |
| 31 | +- Contents: read/write; |
| 32 | +- Pull requests: read/write; |
| 33 | +- Workflows: read/write; |
| 34 | +- Metadata: read. |
| 35 | + |
| 36 | +No organization administration, members, secrets or repository administration |
| 37 | +permissions are required. |
| 38 | + |
| 39 | +## Repository configuration |
| 40 | + |
| 41 | +`LibreCodeCoop/github-workflows` stores: |
| 42 | + |
| 43 | +- Actions variable `LIBRECODE_WORKFLOW_APP_ID`; |
| 44 | +- Actions secret `LIBRECODE_WORKFLOW_APP_PRIVATE_KEY`. |
| 45 | + |
| 46 | +The private key must never be committed to the repository. |
| 47 | + |
| 48 | +## Token model |
| 49 | + |
| 50 | +Workflows do not store a long-lived installation token. |
| 51 | + |
| 52 | +Each write-capable job uses `actions/create-github-app-token`, pinned to a |
| 53 | +full commit SHA, to create a short-lived installation token. |
| 54 | + |
| 55 | +Although the App is installed across the organization, each generated token is |
| 56 | +further restricted to the exact destination repository: |
| 57 | + |
| 58 | +- catalog publisher: `.github`; |
| 59 | +- consumer sync: the current consumer repository from the matrix. |
| 60 | + |
| 61 | +The token also requests only the permissions needed for the operation. |
| 62 | + |
| 63 | +## Onboarding a repository |
| 64 | + |
| 65 | +A new repository does not require reinstalling or reconfiguring the App. |
| 66 | + |
| 67 | +To opt a repository into managed workflow synchronization: |
| 68 | + |
| 69 | +1. validate the desired workflows in that repository; |
| 70 | +2. add the repository and workflow names to `consumers.json`; |
| 71 | +3. merge the reviewed change; |
| 72 | +4. review the automatically created adoption PR; |
| 73 | +5. merge the lock file; |
| 74 | +6. confirm a subsequent synchronization is a no-op. |
| 75 | + |
| 76 | +## Publishing a template |
| 77 | + |
| 78 | +A generated file under `workflow-templates/` is not automatically public. |
| 79 | + |
| 80 | +Add the template name to `workflow-catalog.json` only after the workflow has |
| 81 | +completed its security and consumer validation. |
| 82 | + |
| 83 | +This prevents release, credential-sensitive or experimental workflows from |
| 84 | +appearing in **Actions -> New workflow** prematurely. |
| 85 | + |
| 86 | +## Private-key rotation |
| 87 | + |
| 88 | +Rotate the App private key when: |
| 89 | + |
| 90 | +- compromise is suspected; |
| 91 | +- an administrator with access to the key leaves the responsible team; |
| 92 | +- organizational security policy requires rotation. |
| 93 | + |
| 94 | +Rotation procedure: |
| 95 | + |
| 96 | +1. generate a new private key in the GitHub App settings; |
| 97 | +2. replace `LIBRECODE_WORKFLOW_APP_PRIVATE_KEY` in the repository Actions |
| 98 | + secrets; |
| 99 | +3. run/observe catalog publication and consumer synchronization successfully; |
| 100 | +4. delete the old private key from the GitHub App settings. |
| 101 | + |
| 102 | +Do not delete the old key before the new key has been validated. |
| 103 | + |
| 104 | +## Validation |
| 105 | + |
| 106 | +The initial production validation confirmed: |
| 107 | + |
| 108 | +- GitHub App configuration can be read by Actions; |
| 109 | +- scoped installation tokens can be created; |
| 110 | +- the catalog repository can be checked out and updated; |
| 111 | +- a catalog no-op does not leave an update PR open; |
| 112 | +- `LibreCodeCoop/extract` can be checked out and updated; |
| 113 | +- managed workflows can be adopted into the lock file; |
| 114 | +- a subsequent synchronization with current hashes creates no PR. |
0 commit comments