Skip to content

Commit ae04bd7

Browse files
committed
Attest release image
This improves the release process in a few ways: - Secrets for release are now stored in GitHub environments are only available when required - Release repos now have signed commits and tags - The base image is verified and pinned at the start of the build - The release image is attested and can be easily verified even after the build logs expire - `-dockerhub` tags are created that are the same as the normal version tags
1 parent 90451d6 commit ae04bd7

File tree

1 file changed

+74
-16
lines changed

1 file changed

+74
-16
lines changed

.github/workflows/release.yaml

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,29 @@ on:
44
release:
55
types:
66
- released
7-
workflow_dispatch:
8-
inputs:
9-
tag_name:
10-
description: "Tag to release"
11-
required: true
127

138
permissions:
149
contents: read
1510

1611
jobs:
1712
image:
1813
runs-on: ubuntu-24.04
19-
name: Release Actions
14+
name: Build release image
2015
permissions:
2116
contents: read
2217
packages: write
23-
env:
24-
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
18+
id-token: write
19+
attestations: write
20+
environment:
21+
name: dockerhub
22+
url: https://hub.docker.com/r/danielflook/terraform-github-actions/tags?name=${{ github.event.release.tag_name }}
23+
outputs:
24+
digest: ${{ steps.image_build.outputs.digest }}
2525
steps:
2626
- name: Checkout
2727
uses: actions/checkout@v4
2828
with:
29-
persist-credentials: true
29+
persist-credentials: false
3030

3131
- name: Check action documentation is up-to-date
3232
run: |
@@ -35,7 +35,7 @@ jobs:
3535
3636
- name: Registry login
3737
env:
38-
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
38+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3939
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
4040
run: |
4141
echo $GITHUB_TOKEN | docker login ghcr.io --username dflook --password-stdin
@@ -47,32 +47,87 @@ jobs:
4747
- name: Build action image
4848
id: image_build
4949
env:
50-
RELEASE_TAG: "${{ github.event.release.tag_name }}${{ github.event.inputs.tag_name }}"
50+
RELEASE_TAG: "${{ github.event.release.tag_name }}"
51+
GH_TOKEN: ${{ github.token }}
5152
run: |
53+
BASE_TAG=$(docker buildx imagetools inspect danielflook/terraform-github-actions-base:latest --format '{{json .}}' | jq -r '.manifest.annotations."ref.tag"')
54+
BASE_DIGEST=$(docker buildx imagetools inspect danielflook/terraform-github-actions-base:$BASE_TAG --format '{{json .}}' | jq -r '.manifest.digest')
55+
56+
gh attestation verify --repo dflook/terraform-github-actions "oci://index.docker.io/danielflook/terraform-github-actions-base@$BASE_DIGEST"
57+
58+
sed -i "s|FROM danielflook/terraform-github-actions-base:latest|FROM danielflook/terraform-github-actions-base@$BASE_DIGEST|" "image/Dockerfile"
59+
5260
docker buildx build \
5361
--build-arg FETCH_CHECKSUMS=yes \
5462
--build-arg VERSION="${RELEASE_TAG:1}" \
5563
--tag "danielflook/terraform-github-actions:$RELEASE_TAG" \
5664
--tag "ghcr.io/dflook/terraform-github-actions:$RELEASE_TAG" \
5765
--platform linux/amd64,linux/arm64 \
5866
--attest type=provenance,mode=max,builder-id=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID \
67+
--annotation "index,manifest:org.opencontainers.image.created=$(date '+%Y-%m-%dT%H:%M:%S%z')" \
68+
--annotation "index,manifest:org.opencontainers.image.source=https://github.com/${{ github.repository }}" \
69+
--annotation "index,manifest:org.opencontainers.image.revision=${{ github.sha }}" \
70+
--annotation "index,manifest:org.opencontainers.image.version=$RELEASE_TAG" \
71+
--annotation "index,manifest:org.opencontainers.image.title=terraform-github-actions" \
72+
--annotation "index,manifest:org.opencontainers.image.description=GitHub actions for terraform" \
73+
--annotation "index:org.opencontainers.image.ref.name=docker.io/danielflook/terraform-github-actions:$RELEASE_TAG" \
74+
--annotation "index,manifest:builder-id=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
75+
--annotation "index,manifest:ref.tag=$RELEASE_TAG" \
76+
--annotation "index,manifest:org.opencontainers.image.base.name=docker.io/danielflook/terraform-github-actions-base" \
77+
--annotation "index:org.opencontainers.image.base.ref=$BASE_TAG" \
5978
--push \
6079
--iidfile manifest-list-digest.txt \
6180
image
6281
6382
echo "digest=$(<manifest-list-digest.txt)" >> "$GITHUB_OUTPUT"
6483
84+
- name: Dockerhub ref attestation
85+
uses: actions/attest-build-provenance@v2
86+
with:
87+
subject-name: index.docker.io/danielflook/terraform-github-actions
88+
subject-digest: ${{ steps.image_build.outputs.digest }}
89+
90+
- name: GHCR ref attestation
91+
uses: actions/attest-build-provenance@v2
92+
with:
93+
subject-name: ghcr.io/dflook/terraform-github-actions
94+
subject-digest: ${{ steps.image_build.outputs.digest }}
95+
96+
actions:
97+
runs-on: ubuntu-24.04
98+
name: Release Actions
99+
needs:
100+
- image
101+
environment:
102+
name: release
103+
url: https://github.com/dflook/terraform-github-actions/releases/tag/${{ github.event.release.tag_name }}
104+
steps:
105+
- name: Checkout
106+
uses: actions/checkout@v4
107+
with:
108+
fetch-depth: 0
109+
persist-credentials: false
110+
111+
- name: Configure git
112+
env:
113+
GPG_KEY: ${{ secrets.RELEASE_GPG_KEY }}
114+
run: |
115+
echo "$GPG_KEY" | gpg --import
116+
git config --global user.name "Daniel Flook"
117+
git config --global user.email "daniel@flook.org"
118+
git config --global user.signingkey "26AAA6B35318E5B7CF0823170FDD1CF4BEE12274"
119+
git config --global commit.gpgSign true
120+
git config --global tag.gpgSign true
121+
65122
- name: Release actions
66123
env:
67-
RELEASE_TAG: "${{ github.event.release.tag_name }}${{ github.event.inputs.tag_name }}"
68-
IMAGE_DIGEST: ${{ steps.image_build.outputs.digest }}
124+
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
125+
RELEASE_TAG: "${{ github.event.release.tag_name }}"
126+
IMAGE_DIGEST: ${{ needs.image.outputs.digest }}
69127
run: |
70128
export major=$(echo "$RELEASE_TAG" | cut -d. -f1)
71129
export minor=$(echo "$RELEASE_TAG" | cut -d. -f2)
72130
73-
git config --global user.name "Daniel Flook"
74-
git config --global user.email "daniel@flook.org"
75-
76131
function prepare_release() {
77132
rsync -r "$GITHUB_WORKSPACE/$action/" "$HOME/$action"
78133
rm -rf "$HOME/$action/.github"
@@ -94,6 +149,9 @@ jobs:
94149
git -C "$HOME/$action" tag --force -a -m"$RELEASE_TAG" "$RELEASE_TAG"
95150
git -C "$HOME/$action" tag --force -a -m"$RELEASE_TAG" "$major"
96151
git -C "$HOME/$action" tag --force -a -m"$RELEASE_TAG" "$major.$minor"
152+
git -C "$HOME/$action" tag --force -a -m"$RELEASE_TAG" "$RELEASE_TAG-dockerhub"
153+
git -C "$HOME/$action" tag --force -a -m"$RELEASE_TAG" "$major-dockerhub"
154+
git -C "$HOME/$action" tag --force -a -m"$RELEASE_TAG" "$major.$minor-dockerhub"
97155
git -C "$HOME/$action" push --force
98156
git -C "$HOME/$action" push --force --tags
99157

0 commit comments

Comments
 (0)