-
Notifications
You must be signed in to change notification settings - Fork 25
135 lines (117 loc) · 5.02 KB
/
Copy pathdstack-ingress-release.yml
File metadata and controls
135 lines (117 loc) · 5.02 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
name: dstack-ingress Release
on:
workflow_dispatch:
push:
tags:
- 'dstack-ingress-v*'
permissions:
contents: write
packages: write
attestations: write
id-token: write
jobs:
build-and-attest:
runs-on: ubuntu-latest
env:
IMAGE_REGISTRY: docker.io
IMAGE_REPOSITORY: ${{ vars.DOCKERHUB_ORG }}/dstack-ingress
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Parse and check version
run: |
# The image records its version from the committed VERSION file, so
# that a plain checkout reproduces the digest. The release tag only
# selects which commit to build and must agree with that file.
VERSION=$(tr -d '[:space:]' < custom-domain/dstack-ingress/VERSION)
if [ -z "${VERSION}" ]; then
echo "custom-domain/dstack-ingress/VERSION is empty" >&2
exit 1
fi
case "${GITHUB_REF}" in
refs/tags/dstack-ingress-v*)
TAG_VERSION=${GITHUB_REF#refs/tags/dstack-ingress-v}
if [ "${TAG_VERSION}" != "${VERSION}" ]; then
echo "Tag dstack-ingress-v${TAG_VERSION} does not match custom-domain/dstack-ingress/VERSION (${VERSION})." >&2
echo "Update VERSION and re-tag, so the image version matches the release." >&2
exit 1
fi
;;
*)
echo "This workflow builds a release and must run on a dstack-ingress-v* tag." >&2
echo "Got ref: ${GITHUB_REF}. Re-run it selecting the release tag." >&2
exit 1
;;
esac
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
echo "IMAGE_REFERENCE=${IMAGE_REGISTRY}/${IMAGE_REPOSITORY}:${VERSION}" >> "$GITHUB_ENV"
echo "Parsed version: ${VERSION}"
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y skopeo jq
- name: Log in to Docker registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_REGISTRY }}
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build reproducible image and push
working-directory: custom-domain/dstack-ingress
env:
IMAGE_REFERENCE: ${{ env.IMAGE_REFERENCE }}
run: |
./build-image.sh --require-clean --push "${IMAGE_REFERENCE}"
- name: Capture image digest
id: capture-digest
working-directory: custom-domain/dstack-ingress
run: |
DIGEST=$(skopeo inspect oci-archive:./oci.tar | jq -r '.Digest')
if [ -z "${DIGEST}" ]; then
echo "Failed to determine image digest" >&2
exit 1
fi
echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT"
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: docker.io/${{ env.IMAGE_REPOSITORY }}
subject-digest: ${{ steps.capture-digest.outputs.digest }}
push-to-registry: true
- name: Publish summary
env:
IMAGE_REFERENCE: ${{ env.IMAGE_REFERENCE }}
IMAGE_DIGEST: ${{ steps.capture-digest.outputs.digest }}
run: |
{
echo "## dstack-ingress image"
echo ""
echo "- Tag: \`${IMAGE_REFERENCE}\`"
echo "- Digest: \`${IMAGE_DIGEST}\`"
echo "- Source: \`${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/tree/${GITHUB_SHA}/custom-domain/dstack-ingress\`"
echo "- Sigstore: https://search.sigstore.dev/?hash=${IMAGE_DIGEST}"
} >> "$GITHUB_STEP_SUMMARY"
- name: Release
uses: softprops/action-gh-release@v1
with:
body: |
## Docker Image Digest (SHA256)
| Image | Digest | Verification |
|---|---|---|
| ${{ env.IMAGE_REFERENCE }} | ${{ steps.capture-digest.outputs.digest }} | [Verify on Sigstore](https://search.sigstore.dev/?hash=${{ steps.capture-digest.outputs.digest }}) |
## Source
Built from [`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/tree/${{ github.sha }}/custom-domain/dstack-ingress). The image records its source repository, commit and version as OCI labels and manifest annotations:
```bash
skopeo inspect docker://${{ env.IMAGE_REFERENCE }} | jq .Labels
skopeo inspect --raw docker://${{ env.IMAGE_REFERENCE }} | jq .annotations
```
## Reproducible Build
Build on a native Linux amd64 host with Docker Buildx, Skopeo, jq and Git installed:
```bash
git clone ${{ github.server_url }}/${{ github.repository }}.git
cd dstack-examples/custom-domain/dstack-ingress
git checkout ${{ github.sha }}
./build-image.sh
skopeo inspect oci-archive:./oci.tar | jq -r '.Digest'
```
Expected digest: `${{ steps.capture-digest.outputs.digest }}`