From b183ac3f2522943d285f1a2e188170857379ad76 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:28:45 -0300 Subject: [PATCH 1/7] ci: authenticate cross-repository automation with GitHub App --- .../workflows/publish-workflow-catalog.yml | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-workflow-catalog.yml b/.github/workflows/publish-workflow-catalog.yml index 0210f5d..64e03fd 100644 --- a/.github/workflows/publish-workflow-catalog.yml +++ b/.github/workflows/publish-workflow-catalog.yml @@ -22,14 +22,30 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - name: Validate workflow update token + - name: Validate GitHub App configuration env: - WORKFLOW_UPDATE_TOKEN: ${{ secrets.WORKFLOW_UPDATE_TOKEN }} + WORKFLOW_APP_ID: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} + WORKFLOW_APP_PRIVATE_KEY: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} run: | - if [ -z "$WORKFLOW_UPDATE_TOKEN" ]; then - echo "::error::WORKFLOW_UPDATE_TOKEN is not configured. It must have access to the target repositories and permission to create/update pull requests." + if [ -z "$WORKFLOW_APP_ID" ]; then + echo "::error::LIBRECODE_WORKFLOW_APP_ID is not configured." exit 1 fi + if [ -z "$WORKFLOW_APP_PRIVATE_KEY" ]; then + echo "::error::LIBRECODE_WORKFLOW_APP_PRIVATE_KEY is not configured." + exit 1 + fi + + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + with: + app-id: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} + private-key: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} + owner: LibreCodeCoop + permission-contents: write + permission-pull-requests: write + permission-workflows: write - name: Checkout workflow source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -40,7 +56,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: LibreCodeCoop/.github - token: ${{ secrets.WORKFLOW_UPDATE_TOKEN }} + token: ${{ steps.app-token.outputs.token }} persist-credentials: false path: catalog @@ -54,7 +70,7 @@ jobs: - name: Create catalog update pull request uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: - token: ${{ secrets.WORKFLOW_UPDATE_TOKEN }} + token: ${{ steps.app-token.outputs.token }} path: catalog commit-message: 'chore: sync LibreCode workflow catalog' committer: GitHub From db677b3cf173cff1b0dc7d255f79bddce9a0d2b0 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:40:29 -0300 Subject: [PATCH 2/7] ci: authenticate consumer sync with GitHub App --- .github/workflows/sync-consumers.yml | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/sync-consumers.yml b/.github/workflows/sync-consumers.yml index 428b58f..91d1b13 100644 --- a/.github/workflows/sync-consumers.yml +++ b/.github/workflows/sync-consumers.yml @@ -26,14 +26,30 @@ jobs: outputs: matrix: ${{ steps.matrix.outputs.matrix }} steps: - - name: Validate workflow update token + - name: Validate GitHub App configuration env: - WORKFLOW_UPDATE_TOKEN: ${{ secrets.WORKFLOW_UPDATE_TOKEN }} + WORKFLOW_APP_ID: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} + WORKFLOW_APP_PRIVATE_KEY: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} run: | - if [ -z "$WORKFLOW_UPDATE_TOKEN" ]; then - echo "::error::WORKFLOW_UPDATE_TOKEN is not configured. It must have access to the target repositories and permission to create/update pull requests." + if [ -z "$WORKFLOW_APP_ID" ]; then + echo "::error::LIBRECODE_WORKFLOW_APP_ID is not configured." exit 1 fi + if [ -z "$WORKFLOW_APP_PRIVATE_KEY" ]; then + echo "::error::LIBRECODE_WORKFLOW_APP_PRIVATE_KEY is not configured." + exit 1 + fi + + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + with: + app-id: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} + private-key: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} + owner: LibreCodeCoop + permission-contents: write + permission-pull-requests: write + permission-workflows: write - name: Checkout workflow source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -64,7 +80,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ matrix.repository }} - token: ${{ secrets.WORKFLOW_UPDATE_TOKEN }} + token: ${{ steps.app-token.outputs.token }} persist-credentials: false path: target @@ -87,7 +103,7 @@ jobs: if: ${{ steps.sync.outcome == 'success' }} uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: - token: ${{ secrets.WORKFLOW_UPDATE_TOKEN }} + token: ${{ steps.app-token.outputs.token }} path: target commit-message: 'ci: sync LibreCode workflow templates' committer: GitHub From 00d78574a28418a17575acc89e8c672e8aeb9f6d Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:40:48 -0300 Subject: [PATCH 3/7] fix: create GitHub App token in consumer sync job --- .github/workflows/sync-consumers.yml | 38 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/sync-consumers.yml b/.github/workflows/sync-consumers.yml index 91d1b13..1d9c4fc 100644 --- a/.github/workflows/sync-consumers.yml +++ b/.github/workflows/sync-consumers.yml @@ -25,6 +25,25 @@ jobs: runs-on: ubuntu-latest outputs: matrix: ${{ steps.matrix.outputs.matrix }} + steps: + - name: Checkout workflow source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Build matrix + id: matrix + run: echo "matrix=$(python3 scripts/sync_consumer.py matrix consumers.json)" >> "$GITHUB_OUTPUT" + + sync: + name: Sync ${{ matrix.repository }} + needs: consumers + if: ${{ needs.consumers.outputs.matrix != '{"include":[]}' }} + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.consumers.outputs.matrix) }} + runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Validate GitHub App configuration env: @@ -51,25 +70,6 @@ jobs: permission-pull-requests: write permission-workflows: write - - name: Checkout workflow source - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - name: Build matrix - id: matrix - run: echo "matrix=$(python3 scripts/sync_consumer.py matrix consumers.json)" >> "$GITHUB_OUTPUT" - - sync: - name: Sync ${{ matrix.repository }} - needs: consumers - if: ${{ needs.consumers.outputs.matrix != '{"include":[]}' }} - strategy: - fail-fast: false - matrix: ${{ fromJSON(needs.consumers.outputs.matrix) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - name: Checkout workflow source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: From ff17849b8d985a33db4190d3daf6dcad62edd4f4 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:41:36 -0300 Subject: [PATCH 4/7] feat: expose consumer repository name in sync matrix --- scripts/sync_consumer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/sync_consumer.py b/scripts/sync_consumer.py index 916c3f6..92ac504 100644 --- a/scripts/sync_consumer.py +++ b/scripts/sync_consumer.py @@ -85,6 +85,7 @@ def matrix(consumers: list[Consumer]) -> dict[str, list[dict[str, object]]]: "include": [ { "repository": consumer.repository, + "repository_name": consumer.repository.split("/", 1)[1], "workflows": list(consumer.workflows), } for consumer in consumers From 664f12e7b644b3ac2b18c57258a1c580f45a549d Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:41:40 -0300 Subject: [PATCH 5/7] test: cover scoped consumer repository token input --- tests/test_sync_consumer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_sync_consumer.py b/tests/test_sync_consumer.py index e9f8099..f3501f1 100644 --- a/tests/test_sync_consumer.py +++ b/tests/test_sync_consumer.py @@ -58,6 +58,7 @@ def test_load_consumers_and_matrix(self) -> None: "include": [ { "repository": "LibreCodeCoop/extract", + "repository_name": "extract", "workflows": ["reuse.yml"], } ] From de1186ec03d24ca7447d038ef9f2f0b4e8707d25 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:41:47 -0300 Subject: [PATCH 6/7] security: scope GitHub App tokens to destination repository --- .github/workflows/publish-workflow-catalog.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-workflow-catalog.yml b/.github/workflows/publish-workflow-catalog.yml index 64e03fd..2896932 100644 --- a/.github/workflows/publish-workflow-catalog.yml +++ b/.github/workflows/publish-workflow-catalog.yml @@ -43,6 +43,7 @@ jobs: app-id: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} private-key: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} owner: LibreCodeCoop + repositories: .github permission-contents: write permission-pull-requests: write permission-workflows: write From c2b112cbb1f72f46f4b94e3a2685f4b473a12e64 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Sun, 20 Sep 2026 14:41:50 -0300 Subject: [PATCH 7/7] security: scope GitHub App tokens to destination repository --- .github/workflows/sync-consumers.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sync-consumers.yml b/.github/workflows/sync-consumers.yml index 1d9c4fc..e3a85f7 100644 --- a/.github/workflows/sync-consumers.yml +++ b/.github/workflows/sync-consumers.yml @@ -66,6 +66,7 @@ jobs: app-id: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} private-key: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} owner: LibreCodeCoop + repositories: ${{ matrix.repository_name }} permission-contents: write permission-pull-requests: write permission-workflows: write