diff --git a/.github/scripts/verify-release_workflow_pins.sh b/.github/scripts/verify-release_workflow_pins.sh new file mode 100755 index 00000000..3daea2c8 --- /dev/null +++ b/.github/scripts/verify-release_workflow_pins.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -euo pipefail + +readonly workflow_files=( + ".github/workflows/release.yml" + ".github/workflows/release-bazel.yml" + ".github/workflows/python.yml" +) + +status=0 + +for file in "${workflow_files[@]}"; do + while read -r line_no ref; do + if [[ "$ref" == ./* ]] || [[ "$ref" == docker://* ]]; then + continue + fi + + if [[ ! "$ref" =~ @[0-9a-f]{40}$ ]]; then + printf 'Mutable GitHub Actions ref in %s:%s -> %s\n' "$file" "$line_no" "$ref" >&2 + status=1 + fi + done < <(awk ' + match($0, /^[[:space:]-]*uses:[[:space:]]*([^[:space:]#]+)/, m) { + print NR, m[1] + } + ' "$file") +done + +exit "$status" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b9513e4..4f59f68f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,12 @@ on: permissions: contents: read jobs: + release-workflow-policy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout v4.2.2 + - run: .github/scripts/verify-release_workflow_pins.sh + shell: bash build-appleclang: runs-on: macos-latest strategy: diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 55aee2c8..f1458079 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -37,11 +37,11 @@ jobs: # Bazel fails if the username is unknown. USER: runner steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout v4.2.2 # Stash the timestamp for the commit SHA that triggered the workflow. - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}" shell: bash - - uses: bazel-contrib/setup-bazel@0.15.0 + - uses: bazel-contrib/setup-bazel@4fd964a13a440a8aeb0be47350db2fc640f19ca8 # bazel-contrib/setup-bazel 0.15.0 with: bazelisk-version: '1.x' - name: Prepare Python ${{ matrix.ver }} environment @@ -69,7 +69,7 @@ jobs: "${PYTHON}" re2_test.py shell: bash working-directory: python - - uses: actions/upload-artifact@v4.6.2 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact v4.6.2 with: name: ${{ hashFiles('python/google_re2-*.whl') }} path: python/google_re2-*.whl @@ -98,14 +98,14 @@ jobs: # Otherwise, Python refuses to install the built wheel! SYSTEM_VERSION_COMPAT: 0 steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # actions/checkout v4.1.7 # Stash the timestamp for the commit SHA that triggered the workflow. - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}" shell: bash - - uses: bazel-contrib/setup-bazel@0.15.0 + - uses: bazel-contrib/setup-bazel@4fd964a13a440a8aeb0be47350db2fc640f19ca8 # bazel-contrib/setup-bazel 0.15.0 with: bazelisk-version: '1.x' - - uses: actions/setup-python@v5.6.0 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python v5.6.0 with: python-version: ${{ matrix.ver }} - name: Prepare Python ${{ matrix.ver }} environment @@ -134,7 +134,7 @@ jobs: python re2_test.py shell: bash working-directory: python - - uses: actions/upload-artifact@v4.6.2 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact v4.6.2 with: name: ${{ hashFiles('python/google_re2-*.whl') }} path: python/google_re2-*.whl @@ -160,11 +160,11 @@ jobs: BAZEL_CPU: ${{ matrix.arch.bazel-name }}_windows PLAT_NAME: ${{ matrix.arch.python-name }} steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout v4.2.2 # Stash the timestamp for the commit SHA that triggered the workflow. - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}" shell: bash - - uses: bazel-contrib/setup-bazel@0.15.0 + - uses: bazel-contrib/setup-bazel@4fd964a13a440a8aeb0be47350db2fc640f19ca8 # bazel-contrib/setup-bazel 0.15.0 with: bazelisk-version: '1.x' # Lowercase the architecture name for `actions/setup-python`. @@ -172,7 +172,7 @@ jobs: ARCHITECTURE=${{ matrix.arch.name }} echo "architecture=${ARCHITECTURE,,}" >> "${GITHUB_ENV}" shell: bash - - uses: actions/setup-python@v5.6.0 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python v5.6.0 with: python-version: ${{ matrix.ver }} architecture: ${{ env.architecture }} @@ -201,7 +201,7 @@ jobs: python re2_test.py shell: bash working-directory: python - - uses: actions/upload-artifact@v4.6.2 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact v4.6.2 with: name: ${{ hashFiles('python/google_re2-*.whl') }} path: python/google_re2-*.whl @@ -217,11 +217,11 @@ jobs: id-token: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout v4.2.2 # Stash the timestamp for the commit SHA that triggered the workflow. - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}" shell: bash - - uses: actions/setup-python@v5.6.0 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python v5.6.0 with: python-version: '3.x' - name: Prepare Python 3.x environment @@ -237,7 +237,7 @@ jobs: python -m build --sdist shell: bash working-directory: python - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # actions/download-artifact v4.3.0 with: path: python - name: Set build number to ${{ inputs.build }} @@ -253,6 +253,6 @@ jobs: shell: bash working-directory: python - if: inputs.build >= 1 - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # pypa/gh-action-pypi-publish v1.13.0 with: packages-dir: python/dist diff --git a/.github/workflows/release-bazel.yml b/.github/workflows/release-bazel.yml index 16a0fcfc..8a5f3959 100644 --- a/.github/workflows/release-bazel.yml +++ b/.github/workflows/release-bazel.yml @@ -18,7 +18,7 @@ on: required: true jobs: release: - uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v0.2.2 + uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@096e4724c760aa0024916fe772701c06926f4c49 # bazel-contrib/publish-to-bcr v0.2.2 with: draft: false tag_name: ${{ inputs.tag_name }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd803d4c..783c503e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout v4.2.2 - run: | gh release create "${GITHUB_REF_NAME}" \ --generate-notes --latest --verify-tag \ @@ -28,7 +28,7 @@ jobs: --archive zip \ --repo "${GITHUB_REPOSITORY}" shell: bash - - uses: sigstore/gh-action-sigstore-python@v3.0.1 + - uses: sigstore/gh-action-sigstore-python@f7ad0af51a5648d09a20d00370f0a91c3bdf8f84 # sigstore/gh-action-sigstore-python v3.0.1 with: # N.B. This is a whitespace-separated string! inputs: '*.tar.gz *.zip'