diff --git a/docs/workflow-adoption-model.md b/docs/workflow-adoption-model.md index 38ce0ff..91888f6 100644 --- a/docs/workflow-adoption-model.md +++ b/docs/workflow-adoption-model.md @@ -109,3 +109,23 @@ Before accepting a new shared workflow: - Are permissions least-privilege? - Are third-party actions pinned according to project policy? - Does the consumer have a documented update and divergence path? + +## Consumer lock provenance + +Materialized workflow consumers use `.github/actions-lock.txt` as a management +and provenance record. + +New lock entries use SHA-256 and record: + +- the installed workflow filename; +- the catalog workflow digest; +- the released `github-workflows` platform version; +- the immutable `github-workflows` source commit used by the updater; +- the exact `LibreCodeCoop/.github` catalog commit checked out by the run. + +Legacy two-column MD5 locks remain readable. The next successful synchronization +migrates them deterministically to the provenance format without rewriting a +workflow when its effective bytes are unchanged. + +The consumer-local `.patch` remains authoritative for deliberate +local differences, and unexplained divergence continues to fail closed. diff --git a/patches/nextcloud/sync-workflow-templates.yml.patch b/patches/nextcloud/sync-workflow-templates.yml.patch index 59a4472..2714f63 100644 --- a/patches/nextcloud/sync-workflow-templates.yml.patch +++ b/patches/nextcloud/sync-workflow-templates.yml.patch @@ -33,7 +33,7 @@ name: Update workflows in ${{ matrix.branches }} -@@ -42,12 +45,105 @@ +@@ -42,12 +45,111 @@ with: require: admin @@ -137,10 +137,16 @@ path: source - repository: nextcloud/.github + repository: LibreCodeCoop/.github ++ ++ - name: Record workflow catalog revision ++ id: catalog-revision ++ working-directory: source ++ shell: bash ++ run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - name: Checkout app uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -@@ -56,86 +152,30 @@ +@@ -56,86 +158,33 @@ path: target ref: ${{ matrix.branches }} @@ -209,10 +215,13 @@ - echo "DRAFT_ONLY=${draft_only}" >> $GITHUB_ENV + - name: Synchronize workflow templates + id: sync -+ uses: LibreCodeCoop/github-workflows/actions/sync-workflows@42333e05774f13b83283314079d03614a8beaf82 # v0.1.0 ++ uses: LibreCodeCoop/github-workflows/actions/sync-workflows@002f17274ba1eade3351ba81890bf53674b37c43 # v0.4.0 + with: + source: source/workflow-templates + target: target ++ platform-version: v0.4.0 ++ source-commit: 002f17274ba1eade3351ba81890bf53674b37c43 ++ catalog-commit: ${{ steps.catalog-revision.outputs.sha }} - name: Create Pull Request + if: ${{ steps.sync.outputs.changed == 'true' }} diff --git a/tests/test_portable_workflow_sync_auth.py b/tests/test_portable_workflow_sync_auth.py index e6a24c4..bac0ac7 100644 --- a/tests/test_portable_workflow_sync_auth.py +++ b/tests/test_portable_workflow_sync_auth.py @@ -42,6 +42,24 @@ def test_github_token_limitation_is_visible_in_template(self) -> None: content, ) + def test_sync_action_is_pinned_with_release_and_catalog_provenance(self) -> None: + content = TEMPLATE.read_text(encoding="utf-8") + + self.assertIn( + "actions/sync-workflows@002f17274ba1eade3351ba81890bf53674b37c43 # v0.4.0", + content, + ) + self.assertIn("platform-version: v0.4.0", content) + self.assertIn( + "source-commit: 002f17274ba1eade3351ba81890bf53674b37c43", + content, + ) + self.assertIn("id: catalog-revision", content) + self.assertIn( + "catalog-commit: ${{ steps.catalog-revision.outputs.sha }}", + content, + ) + if __name__ == "__main__": unittest.main() diff --git a/workflow-templates/sync-workflow-templates.yml b/workflow-templates/sync-workflow-templates.yml index 69f1612..e41ce4e 100644 --- a/workflow-templates/sync-workflow-templates.yml +++ b/workflow-templates/sync-workflow-templates.yml @@ -145,6 +145,12 @@ jobs: path: source repository: LibreCodeCoop/.github + - name: Record workflow catalog revision + id: catalog-revision + working-directory: source + shell: bash + run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + - name: Checkout app uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -154,10 +160,13 @@ jobs: - name: Synchronize workflow templates id: sync - uses: LibreCodeCoop/github-workflows/actions/sync-workflows@42333e05774f13b83283314079d03614a8beaf82 # v0.1.0 + uses: LibreCodeCoop/github-workflows/actions/sync-workflows@002f17274ba1eade3351ba81890bf53674b37c43 # v0.4.0 with: source: source/workflow-templates target: target + platform-version: v0.4.0 + source-commit: 002f17274ba1eade3351ba81890bf53674b37c43 + catalog-commit: ${{ steps.catalog-revision.outputs.sha }} - name: Create Pull Request if: ${{ steps.sync.outputs.changed == 'true' }}