-
Notifications
You must be signed in to change notification settings - Fork 2
121 lines (106 loc) · 5.48 KB
/
chainloop_github_release.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# Description: This workflow is used to record a release in Chainloop. It is triggered when a release is published on GitHub.
# It uses the Chainloop CLI to create an attestation for the release assets, source code and additional materials if provided.
# The attestation is then pushed to the Chainloop service and the attestation link is added to the release notes.
# Prior to running this workflow, the Chainloop workflow is onboarded if it does not exist.
# By default, the permission is contents:read to download the release assets. If you want the release notes
# to be updated with the attestation link, modify it to contents:write.
on:
workflow_call:
inputs:
project:
description: "The project this workflow belongs to. default: repository name"
type: string
workflow_name:
description: "The workflow name. default: parent workflow filename"
type: string
additional_materials:
description: "Additional materials to be attested. Commas separated list of values"
type: string
secrets:
api_token:
description: "Reference: https://docs.chainloop.dev/reference/operator/api-tokens#api-tokens"
required: true
cosign_key:
description: "The private key used to sign the attestation"
required: true
cosign_password:
description: "The password for the private key used to sign the attestation"
required: true
jobs:
onboard_workflow:
name: Onboard Chainloop Workflow
uses: chainloop-dev/labs/.github/workflows/chainloop_onboard.yml@main
if: github.event_name == 'release' && github.event.action == 'published'
with:
project: ${{ inputs.project }}
workflow_name: ${{ inputs.workflow_name }}
# Pass parent workflow secrets to the child workflow
secrets: inherit
release:
name: Record release from GitHub
runs-on: ubuntu-latest
needs: onboard_workflow
# Only run this job when a release is published
if: github.event_name == 'release' && github.event.action == 'published'
env:
CHAINLOOP_WORKFLOW_NAME: ${{ needs.onboard_workflow.outputs.workflow_name }}
CHAINLOOP_PROJECT_NAME: ${{ needs.onboard_workflow.outputs.project_name }}
CHAINLOOP_TOKEN: ${{ secrets.api_token }}
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install Chainloop
run: |
curl -sfL https://docs.chainloop.dev/install.sh | bash -s
- name: Initialize Attestation
run: |
chainloop attestation init --workflow-name ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME}
- name: Attest all assets
run: |
# gh release download raises an error if there are not assets on the release
# that makes the workflow fail, so we use `|| true` to avoid that
gh release download ${{github.ref_name}} -D /tmp/github-release || true
for entry in $(ls /tmp/github-release); do
chainloop attestation add --value "/tmp/github-release/$entry"
done
# Include source code
gh release download ${{github.ref_name}} -A tar.gz -O /tmp/github-release/source-code.tar.gz
chainloop attestation add --value "/tmp/github-release/source-code.tar.gz"
# Add additional materials if provided
if [[ -n "${{ inputs.additional_materials }}" ]]; then
for material in $(echo "${{ inputs.additional_materials }}" | tr ',' '\n'); do
chainloop attestation add --value "$material"
done
fi
- name: Finish and Record Attestation
id: attestation-push
if: ${{ success() }}
run: |
chainloop attestation status --full
attestation_sha=$(chainloop attestation push --key env://CHAINLOOP_SIGNING_KEY -o json | jq -r '.digest')
echo "attestation_sha=$attestation_sha" >> $GITHUB_OUTPUT
env:
CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.cosign_password }}
CHAINLOOP_SIGNING_KEY: ${{ secrets.cosign_key }}
- name: Mark attestation as failed
if: ${{ failure() }}
run: |
chainloop attestation reset
- name: Mark attestation as cancelled
if: ${{ cancelled() }}
run: |
chainloop attestation reset --trigger cancellation
- name: Add attestation link to release notes
if: ${{ success() }}
run: |
chainloop_release_url="## Chainloop Attestation"$'\n'"[View the attestation of this release](https://app.chainloop.dev/attestation/${{ steps.attestation-push.outputs.attestation_sha }})"
current_notes=$(gh release view ${{github.ref_name}} --json body -q '.body')
if echo "$current_notes" | grep -q "## Chainloop Attestation"; then
# Replace the existing Chainloop Attestation section with the new URL
modified_notes=$(echo "$current_notes" | sed -E "s|## Chainloop Attestation[^\n]*\n\[View the attestation of this release\]\(https://app\.chainloop\.dev/attestation/[^\)]*\)|$chainloop_release_url|")
else
# Add the Chainloop Attestation section to the top
modified_notes="$chainloop_release_url"$'\n\n'"$current_notes"
fi
# Try to update the release notes with the attestation link. If we don't have enough permissions, we skip it
gh release edit ${{github.ref_name}} -n "$modified_notes" || echo -n "No enough permissions to update the release notes. Skipping..."