Try out new provenance workflow - DO NOT MERGE #1
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build Provenances | ||
on: | ||
workflow_call: | ||
inputs: | ||
build-config-path: | ||
required: true | ||
type: string | ||
secrets: | ||
GCP_SERVICE_ACCOUNT_KEY_JSON: | ||
required: true | ||
jobs: | ||
get_inputs: | ||
outputs: | ||
# Resolves to a single file which is passed to the SLSA provenance | ||
# generator. | ||
artifact-path: ${{ steps.parse-build-config.outputs.artifact-path }} | ||
# The name of the internal TR package. This must coincide with the | ||
# basename of the buildconfig. | ||
package-name: ${{ steps.parse-build-config.outputs.package-name }} | ||
builder-digest: ${{ steps.builder-digest.outputs.builder-digest }} | ||
runs-on: ubuntu-20.04 | ||
steps: | ||
- name: Mount main branch | ||
uses: actions/checkout@v4 | ||
- name: Parse build config | ||
id: parse-build-config | ||
run: | | ||
set -o errexit | ||
set -o nounset | ||
set -o xtrace | ||
set -o pipefail | ||
artifact_path="$(tail -1 ${{ inputs.build-config-path }} | grep -oP 'artifact_path = \K(.*)')" | ||
package_name="$(basename ${{ inputs.build-config-path }} .toml)" | ||
echo "artifact-path=${artifact_path}" >> $GITHUB_OUTPUT | ||
echo "package-name=${package_name}" >> $GITHUB_OUTPUT | ||
- name: Get builder image info | ||
id: builder-digest | ||
run: | | ||
set -o errexit | ||
set -o nounset | ||
set -o xtrace | ||
set -o pipefail | ||
source ./scripts/common | ||
digest="$(echo "${DOCKER_IMAGE_REPO_DIGEST}" | cut -d'@' -f2)" | ||
echo "builder-digest=${digest}" >> $GITHUB_OUTPUT | ||
- name: Print values | ||
run: | | ||
echo "${{ steps.parse-build-config.outputs.artifact-path }}" | ||
echo "${{ steps.parse-build-config.outputs.package-name }}" | ||
echo "${{ steps.builder-digest.outputs.builder-digest }}" | ||
generate_provenance: | ||
needs: [get_inputs] | ||
permissions: | ||
id-token: write | ||
attestations: write | ||
contents: read | ||
uses: actions/attest-build-provenance@v1 | ||
with: | ||
subject-path: ${{ needs.get_inputs.outputs.artifact-path }} | ||
# Uploads the provenance generated in the previous step to GCS. | ||
upload_provenance: | ||
if: | | ||
github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'provenance:force-run') | ||
needs: [get_inputs, generate_provenance] | ||
runs-on: ubuntu-20.04 | ||
permissions: | ||
# Allow the job to update the repo with the latest provenance info and index. | ||
contents: write | ||
steps: | ||
- name: 'Authenticate to Google Cloud' | ||
uses: 'google-github-actions/auth@v2' | ||
with: | ||
credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY_JSON }} | ||
- name: 'Set up Google Cloud SDK' | ||
uses: 'google-github-actions/setup-gcloud@v2' | ||
- name: 'Google Cloud info' | ||
run: | | ||
set -o errexit | ||
set -o nounset | ||
set -o xtrace | ||
set -o pipefail | ||
gcloud --version | ||
gsutil --version | ||
- name: Download the built artifact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: ${{ needs.generate_provenance.outputs.build-outputs-name }} | ||
path: downloads | ||
- name: Download the DSSE document | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: | ||
${{ needs.generate_provenance.outputs.attestations-download-name }} | ||
path: downloads | ||
- name: Debug step - Display structure of downloaded files | ||
run: ls --recursive | ||
working-directory: downloads | ||
- name: Upload binary and provenance | ||
id: upload_binary | ||
working-directory: downloads | ||
# The output on any trigger other than "pull_request" has an additional | ||
# ".sigstore" suffix. However, that suffix appears to be ".build.slsa". | ||
# See https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/docker#workflow-outputs | ||
# The artifact path may be a wildcard that resolves to multiple files. | ||
run: | | ||
set -o errexit | ||
set -o nounset | ||
set -o xtrace | ||
set -o pipefail | ||
bucket_name=oak-bins | ||
provenance_file="attestation.intoto" | ||
if [[ "${{ github.event_name }}" != "pull_request" ]]; then | ||
provenance_file="${provenance_file}.build.slsa" | ||
fi | ||
package_name=${{ needs.get_inputs.outputs.package-name }} | ||
binary_file=${{ needs.get_inputs.outputs.artifact-path }} | ||
binary_digest="$(ent put --digest-format=human --porcelain "${binary_file}")" | ||
provenance_digest="$(ent put --digest-format=human --porcelain "${provenance_file}")" | ||
# Upload the file directly to a dedicated GCS bucket. | ||
binary_path="binary/${GITHUB_SHA}/${package_name}/$(basename ${binary_file})" | ||
gsutil cp "${binary_file}" "gs://${bucket_name}/${binary_path}" | ||
binary_url="https://storage.googleapis.com/${bucket_name}/${binary_path}" | ||
# Index the file via http://static.space so that, regardless of the GCS bucket and path, | ||
# it may be easily located by its digest. | ||
curl --fail \ | ||
--request POST \ | ||
--header 'Content-Type: application/json' \ | ||
--data "{ \"url\": \"${binary_url}\" }" \ | ||
https://api.static.space/v1/snapshot | ||
provenance_path="provenance/${GITHUB_SHA}/${package_name}/$(basename ${provenance_file})" | ||
gsutil cp "${provenance_file}" "gs://${bucket_name}/${provenance_path}" | ||
provenance_url="https://storage.googleapis.com/${bucket_name}/${provenance_path}" | ||
curl --fail \ | ||
--request POST \ | ||
--header 'Content-Type: application/json' \ | ||
--data "{ \"url\": \"${provenance_url}\" }" \ | ||
https://api.static.space/v1/snapshot | ||
# Debug step similar to `upload_provenance`, but runs on pull-request events. | ||
# Differs from `upload_provenance` in that it does not publish anything. | ||
debug_provenance: | ||
if: github.event_name == 'pull_request' | ||
needs: [get_inputs, generate_provenance] | ||
runs-on: ubuntu-20.04 | ||
steps: | ||
- name: Download the built artifact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: ${{ needs.generate_provenance.outputs.build-outputs-name }} | ||
path: downloads | ||
- name: Download the DSSE document | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: | ||
${{ needs.generate_provenance.outputs.attestations-download-name }} | ||
path: downloads | ||
- name: Display structure after downloading the files (debug step) | ||
run: ls --recursive | ||
working-directory: downloads | ||
- name: Print binary digest | ||
working-directory: downloads | ||
run: echo "$(sha256sum ${{ needs.get_inputs.outputs.artifact-path }})" | ||
- name: Print provenance digest | ||
working-directory: downloads | ||
run: | | ||
echo "$(sha256sum attestation.intoto)" |