From 9da4e56a8389a5f3370c139c6916bbe1a8469d8d Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Tue, 29 Oct 2024 13:27:56 +1000 Subject: [PATCH] Don't cache git credentials in workflows (#51) Address zizmor scan results, and set up a workflow to scan them in CI after the repo has been published. Includes a small update to the launch modules in the sample project so the PR generation for output updates has been tested with the updated workflow. Implements most of #50 --- .github/workflows/docs.yml | 2 + .github/workflows/publish.yml | 2 + .github/workflows/scan-workflows.yml | 41 +++++++++++++++++++ .github/workflows/test.yml | 5 +++ .github/workflows/update-expected-output.yml | 4 ++ .gitignore | 1 + .../env_metadata/app-scipy-client.json | 6 +-- .../env_metadata/app-scipy-import.json | 6 +-- .../env_metadata/app-sklearn-import.json | 6 +-- .../linux_x86_64/venvstacks.json | 18 ++++---- .../env_metadata/app-scipy-client.json | 6 +-- .../env_metadata/app-scipy-import.json | 6 +-- .../macosx_arm64/venvstacks.json | 12 +++--- .../env_metadata/app-scipy-client.json | 6 +-- .../env_metadata/app-scipy-import.json | 6 +-- .../win_amd64/venvstacks.json | 12 +++--- .../launch_modules/scipy_client/cli.py | 7 ++++ .../launch_modules/scipy_import.py | 6 +++ .../launch_modules/sklearn_import.py | 7 ++++ 19 files changed, 117 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/scan-workflows.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9730b9a..066e238 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -31,6 +31,8 @@ jobs: # for latest versions if the standard actions start emitting warnings steps: - uses: actions/checkout@v4 + with: + persist-credentials: false # sphinx-action uses docker under the hood and doesn't play nice with the # dependency caching, so it may be better to switch to using `tox -e docs` diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b286532..e2f79f3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,6 +15,8 @@ jobs: id-token: write steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: pdm-project/setup-pdm@v4 with: diff --git a/.github/workflows/scan-workflows.yml b/.github/workflows/scan-workflows.yml new file mode 100644 index 0000000..fb84502 --- /dev/null +++ b/.github/workflows/scan-workflows.yml @@ -0,0 +1,41 @@ +name: "Scan workflows" + +on: + pull_request: + branches: + - "**" + paths: + # Run for changes to *any* workflow file + - ".github/workflows/*.yml" + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + permissions: + # required for all workflows + security-events: write + # only required for workflows in private repositories + actions: read + contents: read + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install zizmor + run: cargo install zizmor + + - name: Scan workflows + run: + zizmor --format=sarif . | tee workflow-scan.sarif + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: github/codeql-action/upload-sarif@v3 + if: always() + with: + # Path to SARIF file relative to the root of the repository + sarif_file: workflow-scan.sarif diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 57a5a95..73c891f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,6 +48,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Capture timestamp for debugging artifacts id: timestamp @@ -149,6 +151,9 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: actions/setup-python@v5 with: # Use latest Python, so it understands all syntax. diff --git a/.github/workflows/update-expected-output.yml b/.github/workflows/update-expected-output.yml index fda9fcf..f43940a 100644 --- a/.github/workflows/update-expected-output.yml +++ b/.github/workflows/update-expected-output.yml @@ -65,6 +65,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 @@ -183,6 +185,8 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.head_ref }} + # The PR creation step below needs git push credentials + persist-credentials: true - name: Download all updated output files uses: actions/download-artifact@v4 diff --git a/.gitignore b/.gitignore index 063f8c9..898852d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Artifacts exported from CI by test suite /export/ +*.sarif # VSCode config is platform specific .vscode diff --git a/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-client.json b/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-client.json index 262d36b..6636940 100644 --- a/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-client.json +++ b/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-client.json @@ -1,12 +1,12 @@ { "app_launch_module": "scipy_client", - "app_launch_module_hash": "sha256/344b1be70920bd9635ce38fa14fca86b531ce2e334f54968321469c5fbb5b608", + "app_launch_module_hash": "sha256/bbe4da6de13a8f13a05cdd2bb3b90884861a6636b1450248d03aea799a7fc828", "archive_build": 1, "archive_hashes": { - "sha256": "737a6b60e3be2fed00a8d1385973bf9526b25250a8fa2dd65d288925fcfa341b" + "sha256": "84c38c5717c3ff4e5fc9a13b22045b8c7fa2a96682648e419e22983e9023f554" }, "archive_name": "app-scipy-client.tar.xz", - "archive_size": 1424, + "archive_size": 1504, "install_target": "app-scipy-client", "layer_name": "app-scipy-client", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-import.json b/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-import.json index ae87b80..36b7bde 100644 --- a/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-import.json +++ b/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-scipy-import.json @@ -1,12 +1,12 @@ { "app_launch_module": "scipy_import", - "app_launch_module_hash": "sha256:6278ff255372146d752518ffdf49f3432667d7c93997ed980b3676fdc75406ee", + "app_launch_module_hash": "sha256:d806d778921ad216c1f950886d27b4b77e5561fe3467046fec258805980cc6d1", "archive_build": 1, "archive_hashes": { - "sha256": "2d8d19d109288cdc91a643e7b3fd9bcbc9fa38d40bbafe631074878245cb038f" + "sha256": "4c30fb1472a1905d0369b700bd922f317f8ab4875e7b02a9c997dedf5cb0b175" }, "archive_name": "app-scipy-import.tar.xz", - "archive_size": 1336, + "archive_size": 1412, "install_target": "app-scipy-import", "layer_name": "app-scipy-import", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-sklearn-import.json b/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-sklearn-import.json index 9373fa3..76a2b85 100644 --- a/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-sklearn-import.json +++ b/tests/sample_project/expected_manifests/linux_x86_64/env_metadata/app-sklearn-import.json @@ -1,12 +1,12 @@ { "app_launch_module": "sklearn_import", - "app_launch_module_hash": "sha256:b6de2b52093004bcc39df16d115929021937f77b5feda45d090b06116ea34f49", + "app_launch_module_hash": "sha256:f66c01bbcca47cd31d79d2fb5377de0de18631ffc3c904629d46f6cad2918694", "archive_build": 1, "archive_hashes": { - "sha256": "dd778c5f82c1c1ee62765d876a063dba4b374b6f4e06842104c8945e66663748" + "sha256": "ba0b38bb3c8539b9882bdfd752f1407961f26fe8a2c1af3d1bed62d83478b8e7" }, "archive_name": "app-sklearn-import.tar.xz", - "archive_size": 1332, + "archive_size": 1420, "install_target": "app-sklearn-import", "layer_name": "app-sklearn-import", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/linux_x86_64/venvstacks.json b/tests/sample_project/expected_manifests/linux_x86_64/venvstacks.json index 2227400..f1bd931 100644 --- a/tests/sample_project/expected_manifests/linux_x86_64/venvstacks.json +++ b/tests/sample_project/expected_manifests/linux_x86_64/venvstacks.json @@ -3,13 +3,13 @@ "applications": [ { "app_launch_module": "scipy_import", - "app_launch_module_hash": "sha256:6278ff255372146d752518ffdf49f3432667d7c93997ed980b3676fdc75406ee", + "app_launch_module_hash": "sha256:d806d778921ad216c1f950886d27b4b77e5561fe3467046fec258805980cc6d1", "archive_build": 1, "archive_hashes": { - "sha256": "2d8d19d109288cdc91a643e7b3fd9bcbc9fa38d40bbafe631074878245cb038f" + "sha256": "4c30fb1472a1905d0369b700bd922f317f8ab4875e7b02a9c997dedf5cb0b175" }, "archive_name": "app-scipy-import.tar.xz", - "archive_size": 1336, + "archive_size": 1412, "install_target": "app-scipy-import", "layer_name": "app-scipy-import", "lock_version": 1, @@ -23,13 +23,13 @@ }, { "app_launch_module": "scipy_client", - "app_launch_module_hash": "sha256/344b1be70920bd9635ce38fa14fca86b531ce2e334f54968321469c5fbb5b608", + "app_launch_module_hash": "sha256/bbe4da6de13a8f13a05cdd2bb3b90884861a6636b1450248d03aea799a7fc828", "archive_build": 1, "archive_hashes": { - "sha256": "737a6b60e3be2fed00a8d1385973bf9526b25250a8fa2dd65d288925fcfa341b" + "sha256": "84c38c5717c3ff4e5fc9a13b22045b8c7fa2a96682648e419e22983e9023f554" }, "archive_name": "app-scipy-client.tar.xz", - "archive_size": 1424, + "archive_size": 1504, "install_target": "app-scipy-client", "layer_name": "app-scipy-client", "lock_version": 1, @@ -44,13 +44,13 @@ }, { "app_launch_module": "sklearn_import", - "app_launch_module_hash": "sha256:b6de2b52093004bcc39df16d115929021937f77b5feda45d090b06116ea34f49", + "app_launch_module_hash": "sha256:f66c01bbcca47cd31d79d2fb5377de0de18631ffc3c904629d46f6cad2918694", "archive_build": 1, "archive_hashes": { - "sha256": "dd778c5f82c1c1ee62765d876a063dba4b374b6f4e06842104c8945e66663748" + "sha256": "ba0b38bb3c8539b9882bdfd752f1407961f26fe8a2c1af3d1bed62d83478b8e7" }, "archive_name": "app-sklearn-import.tar.xz", - "archive_size": 1332, + "archive_size": 1420, "install_target": "app-sklearn-import", "layer_name": "app-sklearn-import", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-client.json b/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-client.json index 531d8ab..a9a8af9 100644 --- a/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-client.json +++ b/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-client.json @@ -1,12 +1,12 @@ { "app_launch_module": "scipy_client", - "app_launch_module_hash": "sha256/344b1be70920bd9635ce38fa14fca86b531ce2e334f54968321469c5fbb5b608", + "app_launch_module_hash": "sha256/bbe4da6de13a8f13a05cdd2bb3b90884861a6636b1450248d03aea799a7fc828", "archive_build": 1, "archive_hashes": { - "sha256": "b4f061f14023391f588940cb8f509ae8c46dd8fca552346c15df153f09eeb85d" + "sha256": "2cdf88d7a5ed2dca88d7a59e2b5d9744503cf824218371948000f1b08486df4e" }, "archive_name": "app-scipy-client.tar.xz", - "archive_size": 1400, + "archive_size": 1484, "install_target": "app-scipy-client", "layer_name": "app-scipy-client", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-import.json b/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-import.json index 1e30333..2cbf816 100644 --- a/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-import.json +++ b/tests/sample_project/expected_manifests/macosx_arm64/env_metadata/app-scipy-import.json @@ -1,12 +1,12 @@ { "app_launch_module": "scipy_import", - "app_launch_module_hash": "sha256:6278ff255372146d752518ffdf49f3432667d7c93997ed980b3676fdc75406ee", + "app_launch_module_hash": "sha256:d806d778921ad216c1f950886d27b4b77e5561fe3467046fec258805980cc6d1", "archive_build": 1, "archive_hashes": { - "sha256": "a7d51a74e9c5b370af3038bb5abb08fd81b49b446c02e6c16ff6b1fd9ac9025b" + "sha256": "5034f1fa0a0731af9e88699519a508e72662b003c30e14814ce72e00ef8a6223" }, "archive_name": "app-scipy-import.tar.xz", - "archive_size": 1284, + "archive_size": 1392, "install_target": "app-scipy-import", "layer_name": "app-scipy-import", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/macosx_arm64/venvstacks.json b/tests/sample_project/expected_manifests/macosx_arm64/venvstacks.json index 28ac820..86778c7 100644 --- a/tests/sample_project/expected_manifests/macosx_arm64/venvstacks.json +++ b/tests/sample_project/expected_manifests/macosx_arm64/venvstacks.json @@ -3,13 +3,13 @@ "applications": [ { "app_launch_module": "scipy_import", - "app_launch_module_hash": "sha256:6278ff255372146d752518ffdf49f3432667d7c93997ed980b3676fdc75406ee", + "app_launch_module_hash": "sha256:d806d778921ad216c1f950886d27b4b77e5561fe3467046fec258805980cc6d1", "archive_build": 1, "archive_hashes": { - "sha256": "a7d51a74e9c5b370af3038bb5abb08fd81b49b446c02e6c16ff6b1fd9ac9025b" + "sha256": "5034f1fa0a0731af9e88699519a508e72662b003c30e14814ce72e00ef8a6223" }, "archive_name": "app-scipy-import.tar.xz", - "archive_size": 1284, + "archive_size": 1392, "install_target": "app-scipy-import", "layer_name": "app-scipy-import", "lock_version": 1, @@ -23,13 +23,13 @@ }, { "app_launch_module": "scipy_client", - "app_launch_module_hash": "sha256/344b1be70920bd9635ce38fa14fca86b531ce2e334f54968321469c5fbb5b608", + "app_launch_module_hash": "sha256/bbe4da6de13a8f13a05cdd2bb3b90884861a6636b1450248d03aea799a7fc828", "archive_build": 1, "archive_hashes": { - "sha256": "b4f061f14023391f588940cb8f509ae8c46dd8fca552346c15df153f09eeb85d" + "sha256": "2cdf88d7a5ed2dca88d7a59e2b5d9744503cf824218371948000f1b08486df4e" }, "archive_name": "app-scipy-client.tar.xz", - "archive_size": 1400, + "archive_size": 1484, "install_target": "app-scipy-client", "layer_name": "app-scipy-client", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-client.json b/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-client.json index 89a0d76..a32e876 100644 --- a/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-client.json +++ b/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-client.json @@ -1,12 +1,12 @@ { "app_launch_module": "scipy_client", - "app_launch_module_hash": "sha256/344b1be70920bd9635ce38fa14fca86b531ce2e334f54968321469c5fbb5b608", + "app_launch_module_hash": "sha256/bbe4da6de13a8f13a05cdd2bb3b90884861a6636b1450248d03aea799a7fc828", "archive_build": 1, "archive_hashes": { - "sha256": "a4229a9be2b24b0739b11729278d9acb68320b1d36b1f2a7d46191b359f4df74" + "sha256": "69060c0e0a74290723c5e65a343e463112a249da960d8bf29997933cd1565787" }, "archive_name": "app-scipy-client.zip", - "archive_size": 255062, + "archive_size": 255147, "install_target": "app-scipy-client", "layer_name": "app-scipy-client", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-import.json b/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-import.json index 75bff50..be1e7d7 100644 --- a/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-import.json +++ b/tests/sample_project/expected_manifests/win_amd64/env_metadata/app-scipy-import.json @@ -1,12 +1,12 @@ { "app_launch_module": "scipy_import", - "app_launch_module_hash": "sha256:6278ff255372146d752518ffdf49f3432667d7c93997ed980b3676fdc75406ee", + "app_launch_module_hash": "sha256:d806d778921ad216c1f950886d27b4b77e5561fe3467046fec258805980cc6d1", "archive_build": 1, "archive_hashes": { - "sha256": "3ebb818738bdd10e5eebdb48fda4be41ac73af88890ba9f749c7dbb23ce2aaa8" + "sha256": "1907700fc74c6a0bc62d851dce87bfed6a0ad52d0fec5863c9eadd1e26c029ff" }, "archive_name": "app-scipy-import.zip", - "archive_size": 254578, + "archive_size": 254658, "install_target": "app-scipy-import", "layer_name": "app-scipy-import", "lock_version": 1, diff --git a/tests/sample_project/expected_manifests/win_amd64/venvstacks.json b/tests/sample_project/expected_manifests/win_amd64/venvstacks.json index f9690d0..d06983c 100644 --- a/tests/sample_project/expected_manifests/win_amd64/venvstacks.json +++ b/tests/sample_project/expected_manifests/win_amd64/venvstacks.json @@ -3,13 +3,13 @@ "applications": [ { "app_launch_module": "scipy_import", - "app_launch_module_hash": "sha256:6278ff255372146d752518ffdf49f3432667d7c93997ed980b3676fdc75406ee", + "app_launch_module_hash": "sha256:d806d778921ad216c1f950886d27b4b77e5561fe3467046fec258805980cc6d1", "archive_build": 1, "archive_hashes": { - "sha256": "3ebb818738bdd10e5eebdb48fda4be41ac73af88890ba9f749c7dbb23ce2aaa8" + "sha256": "1907700fc74c6a0bc62d851dce87bfed6a0ad52d0fec5863c9eadd1e26c029ff" }, "archive_name": "app-scipy-import.zip", - "archive_size": 254578, + "archive_size": 254658, "install_target": "app-scipy-import", "layer_name": "app-scipy-import", "lock_version": 1, @@ -23,13 +23,13 @@ }, { "app_launch_module": "scipy_client", - "app_launch_module_hash": "sha256/344b1be70920bd9635ce38fa14fca86b531ce2e334f54968321469c5fbb5b608", + "app_launch_module_hash": "sha256/bbe4da6de13a8f13a05cdd2bb3b90884861a6636b1450248d03aea799a7fc828", "archive_build": 1, "archive_hashes": { - "sha256": "a4229a9be2b24b0739b11729278d9acb68320b1d36b1f2a7d46191b359f4df74" + "sha256": "69060c0e0a74290723c5e65a343e463112a249da960d8bf29997933cd1565787" }, "archive_name": "app-scipy-client.zip", - "archive_size": 255062, + "archive_size": 255147, "install_target": "app-scipy-client", "layer_name": "app-scipy-client", "lock_version": 1, diff --git a/tests/sample_project/launch_modules/scipy_client/cli.py b/tests/sample_project/launch_modules/scipy_client/cli.py index a48054b..2274de6 100644 --- a/tests/sample_project/launch_modules/scipy_client/cli.py +++ b/tests/sample_project/launch_modules/scipy_client/cli.py @@ -1,5 +1,6 @@ """Sample CLI helper module importing scipy and httpx""" +import numpy import scipy import httpx @@ -11,4 +12,10 @@ def main(): for disallowed in ("pip", "sklearn"): if find_spec(disallowed): raise RuntimeError(f"Should not be able to import {disallowed!r}!") + + for module in (numpy, scipy, httpx): + # This is just here to allow the launch modules to pass lint checks + assert module.__spec__ is not None + assert find_spec(module.__spec__.name) is not None + print("Environment launch module executed successfully") diff --git a/tests/sample_project/launch_modules/scipy_import.py b/tests/sample_project/launch_modules/scipy_import.py index 17ae63d..0a8c190 100644 --- a/tests/sample_project/launch_modules/scipy_import.py +++ b/tests/sample_project/launch_modules/scipy_import.py @@ -1,5 +1,6 @@ """Sample launch module importing scipy""" +import numpy import scipy if __name__ == "__main__": @@ -10,4 +11,9 @@ if find_spec(disallowed): raise RuntimeError(f"Should not be able to import {disallowed!r}!") + for module in (numpy, scipy): + # This is just here to allow the launch modules to pass lint checks + assert module.__spec__ is not None + assert find_spec(module.__spec__.name) is not None + print("Environment launch module executed successfully") diff --git a/tests/sample_project/launch_modules/sklearn_import.py b/tests/sample_project/launch_modules/sklearn_import.py index 2196c19..510919a 100644 --- a/tests/sample_project/launch_modules/sklearn_import.py +++ b/tests/sample_project/launch_modules/sklearn_import.py @@ -1,5 +1,7 @@ """Sample launch module importing sklearn""" +import numpy +import scipy import sklearn if __name__ == "__main__": @@ -10,4 +12,9 @@ if find_spec(disallowed): raise RuntimeError(f"Should not be able to import {disallowed!r}!") + for module in (numpy, scipy, sklearn): + # This is just here to allow the launch modules to pass lint checks + assert module.__spec__ is not None + assert find_spec(module.__spec__.name) is not None + print("Environment launch module executed successfully")