workflows: Factor out artifact attestation and upload into a composite action (#169621)

Also, switch the release-sources workflow over to use this new action.
As a result of this change, the attestation file for the sources will be
renamed from attestation.jsonl to $TAG-sources-attestation.jsonl.
This commit is contained in:
Tom Stellard 2025-12-03 10:27:28 -08:00 committed by GitHub
parent 2221f4a06e
commit a8ccd42ab2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 142 additions and 20 deletions

View file

@ -64,11 +64,11 @@ jobs:
name: Package Release Sources
if: github.repository_owner == 'llvm'
runs-on: ubuntu-24.04
outputs:
digest: ${{ steps.digest.outputs.digest }}
artifact-id: ${{ steps.artifact-upload.outputs.artifact-id }}
needs:
- inputs
permissions:
id-token: write
attestations: write
steps:
- name: Checkout LLVM
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
@ -79,30 +79,47 @@ jobs:
run: |
pip install --require-hashes -r ./llvm/utils/git/requirements.txt
- name: Check Permissions
if: github.event_name != 'pull_request'
env:
GITHUB_TOKEN: ${{ github.token }}
USER_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }}
run: |
./llvm/utils/release/./github-upload-release.py --token "$GITHUB_TOKEN" --user ${{ github.actor }} --user-token "$USER_TOKEN" check-permissions
- name: Create Tarballs
run: |
./llvm/utils/release/export.sh ${{ needs.inputs.outputs.export-args }}
- name: Attest Build Provenance
if: github.event_name != 'pull_request'
id: provenance
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-path: "*.xz"
- if: github.event_name != 'pull_request'
- name: Generate sha256 digest for sources
id: digest
run: |
mv ${{ steps.provenance.outputs.bundle-path }} .
- name: Create Tarball Artifacts
echo "digest=$(cat *.xz | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
- name: Release Sources Artifact
id: artifact-upload
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: ${{ needs.inputs.outputs.ref }}-sources
path: |
*.xz
attestation.jsonl
attest-release-sources:
name: Attest Release Sources
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- inputs
- release-sources
permissions:
id-token: write
attestations: write
steps:
- name: Checkout Release Scripts
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
sparse-checkout: |
.github/workflows/upload-release-artifact
llvm/utils/release/github-upload-release.py
llvm/utils/git/requirements.txt
sparse-checkout-cone-mode: false
- name: Upload Artifacts
uses: ./.github/workflows/upload-release-artifact
with:
artifact-id: ${{ needs.release-sources.outputs.artifact-id }}
attestation-name: ${{ needs.inputs.outputs.ref }}-sources-attestation
digest: ${{ needs.release-sources.outputs.digest }}
upload: false

View file

@ -0,0 +1,105 @@
name: Upload Release Artifact
description: >-
Upload release artifact along with an attestation. The action assumes that
the llvm-project repository has already been checked out.
inputs:
release-version:
description: >-
The release where the artifact will be attached.
required: true
upload:
description: >-
Whether or not to upload the file and attestation to the release. If this
is set to false, then the file will be uploaded to the job as an artifact,
but no atteastion will be generated and the artifact won't be uploaded
to the release.
default: true
user-token:
description: >-
Token with premissions to read llvm teams that is used to ensure that
the person who triggred the action has permission to upload artifacts.
This is required if upload is true.
requred: false
attestation-name:
description: >-
This will be used for the artifact name that is attached to the workflow and
will be used as the basename for the attestation file which will be called
$attestation-name.jsonl. If this is not set, it will default
to the falue of `files`.
required: false
artifact-id:
description: >-
Artifact id of the artifact with the files to upload.
required: true
digest:
description: >-
sha256 digest to verify the authenticity of the files being uploaded.
required: true
runs:
using: "composite"
steps:
- name: Download Artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
id: download-artifact
with:
artifact-ids: ${{ inputs.artifact-id }}
path: downloads
# In theory github artifacts are immutable so we could just rely on using
# the artifact-id to download it, but just to be extra safe we want to
# generated a digest for the files we are uploading so we can verify it
# when downloading.
# See also: https://irsl.medium.com/github-artifact-immutability-is-a-lie-9b6244095694
- name: Verify Files
shell: bash
env:
INPUTS_DIGEST: ${{ inputs.digest }}
run: |
digest_file="sha256"
echo "$INPUTS_DIGEST -" > $digest_file
cat ${{ steps.download-artifact.outputs.download-path }}/* | sha256sum -c $digest_file
- name: Attest Build Provenance
id: provenance
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-path: ${{ steps.download-artifact.outputs.download-path }}/*
- name: Rename attestation file
shell: bash
env:
INPUTS_ATTESTATION_NAME: ${{ inputs.attestation-name }}
run: |
mv ${{ steps.provenance.outputs.bundle-path }} "$INPUTS_ATTESTATION_NAME".jsonl
- name: Upload Build Provenance
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: ${{ inputs.attestation-name }}
path: |
${{ inputs.attestation-name }}.jsonl
- name: Install Python Requirements
if: inputs.upload == 'true'
shell: bash
run: |
pip install --require-hashes -r ./llvm/utils/git/requirements.txt
- name: Check Permissions
if: inputs.upload == 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
USER_TOKEN: ${{ inputs.user-token }}
shell: bash
run: |
./llvm/utils/release/./github-upload-release.py --token "$GITHUB_TOKEN" --user "$GITHUB_ACTOR" --user-token "$USER_TOKEN" check-permissions
- name: Upload Release
shell: bash
if: inputs.upload == 'true'
run: |
./llvm/utils/release/github-upload-release.py \
--token ${{ github.token }} \
--release ${{ inputs.release-version }} \
upload \
--files ${{ steps.download-artifact.outputs.download-path }}/* ${{ steps.vars.outputs.attestation-name}}.jsonl