Skip to content

Commit 647cf95

Browse files
committed
ci: publish signed cluster OCI artifact
1 parent c303bf9 commit 647cf95

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
# yaml-language-server: $schema=https://www.schemastore.org/github-workflow.json
3+
name: Cluster Release
4+
5+
on:
6+
workflow_dispatch:
7+
push:
8+
branches:
9+
- main
10+
paths:
11+
- .github/workflows/cluster-release.yaml
12+
- kubernetes/**
13+
14+
concurrency:
15+
group: cluster-release
16+
cancel-in-progress: true
17+
18+
permissions:
19+
contents: read
20+
id-token: write
21+
packages: write
22+
23+
env:
24+
OCI_REPOSITORY: ghcr.io/jfroy/flatops/cluster
25+
26+
jobs:
27+
release:
28+
if: github.ref == 'refs/heads/main'
29+
name: Build, Sign, and Publish
30+
runs-on: ubuntu-latest
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
34+
with:
35+
persist-credentials: false
36+
37+
- name: Setup Flux CLI
38+
uses: fluxcd/flux2/action@889be9d6cc8afa8ed639e1e1ba4ab678e3b38d8c # v2.9.4
39+
with:
40+
token: ${{ github.token }}
41+
version: 2.9.4
42+
43+
- name: Setup Cosign
44+
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
45+
with:
46+
cosign-release: v3.1.3
47+
48+
- name: Login to GHCR
49+
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
50+
with:
51+
registry: ghcr.io
52+
username: ${{ github.actor }}
53+
password: ${{ github.token }}
54+
55+
- name: Build cluster artifact
56+
env:
57+
ARTIFACT_DIR: ${{ runner.temp }}/cluster-artifact
58+
ARTIFACT_TGZ: ${{ runner.temp }}/cluster-artifact.tgz
59+
run: |
60+
mkdir -p "${ARTIFACT_DIR}/kubernetes"
61+
cp -a kubernetes/. "${ARTIFACT_DIR}/kubernetes/"
62+
flux build artifact \
63+
--path "${ARTIFACT_DIR}" \
64+
--output "${ARTIFACT_TGZ}"
65+
tar -tzf "${ARTIFACT_TGZ}" > "${ARTIFACT_TGZ}.files"
66+
grep -q 'kubernetes/cluster/ks.yaml$' "${ARTIFACT_TGZ}.files"
67+
68+
- name: Publish immutable artifact
69+
id: publish
70+
env:
71+
ARTIFACT_DIR: ${{ runner.temp }}/cluster-artifact
72+
run: |
73+
result="$(flux push artifact "oci://${OCI_REPOSITORY}:${GITHUB_SHA}" \
74+
--path "${ARTIFACT_DIR}" \
75+
--source "https://github.com/${GITHUB_REPOSITORY}" \
76+
--revision "main@sha1:${GITHUB_SHA}" \
77+
--annotations "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}" \
78+
--output json)"
79+
digest="$(jq -er '.digest' <<< "${result}")"
80+
echo "digest=${digest}" >> "${GITHUB_OUTPUT}"
81+
82+
- name: Sign and verify artifact
83+
env:
84+
DIGEST: ${{ steps.publish.outputs.digest }}
85+
run: |
86+
cosign sign --yes "${OCI_REPOSITORY}@${DIGEST}"
87+
cosign verify \
88+
--certificate-identity "https://github.com/jfroy/flatops/.github/workflows/cluster-release.yaml@refs/heads/main" \
89+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
90+
"${OCI_REPOSITORY}@${DIGEST}"
91+
92+
- name: Promote artifact
93+
run: |
94+
flux tag artifact "oci://${OCI_REPOSITORY}:${GITHUB_SHA}" --tag latest
95+
96+
- name: Verify anonymous pull access
97+
env:
98+
DIGEST: ${{ steps.publish.outputs.digest }}
99+
DOCKER_CONFIG: ${{ runner.temp }}/anonymous-docker-config
100+
run: |
101+
mkdir -p "${DOCKER_CONFIG}" "${RUNNER_TEMP}/pulled-artifact"
102+
flux pull artifact "oci://${OCI_REPOSITORY}@${DIGEST}" \
103+
--output "${RUNNER_TEMP}/pulled-artifact"

0 commit comments

Comments
 (0)