Skip to content

Commit 3873bf4

Browse files
committed
PLAT-1431 Added Release workflow
1 parent 69d540c commit 3873bf4

File tree

11 files changed

+307
-27
lines changed

11 files changed

+307
-27
lines changed

.github/actions/policy-matrix/action.yaml renamed to .github/actions/calculate-policy-matrix/action.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ runs:
1414
git remote -v
1515
1616
policies_working_dirs=($(find policies -maxdepth 2 -name Makefile -exec dirname '{}' \;))
17+
1718
if [ "${{github.event_name}}" == "pull_request" ]; then
1819
# list only changes of files in `policies/`:
1920
git_files="$(git diff --no-color --find-renames --find-copies --name-only origin/${{ github.base_ref }} ${{ github.sha }} -- policies)"
@@ -22,7 +23,7 @@ runs:
2223
policies_working_dirs=($(echo "$git_files" | cut -d/ -f1,2 ))
2324
fi
2425
25-
declare -p policies_working_dirs # for debug
26+
declare -p policies_working_dirs
2627
policy_working_dirs=$(jq --compact-output --null-input '$ARGS.positional | map(select(. != "policies/Cargo.lock" and . != "policies/Cargo.toml" and . != "policies/go.mod" and . != "policies/go.sum")) | unique' --args -- "${policies_working_dirs[@]}")
2728
echo "policy_working_dirs=$policy_working_dirs"
2829
echo "policy_working_dirs=$policy_working_dirs" >> $GITHUB_OUTPUT

.github/actions/get-policy-metadata/action.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ inputs:
66
policy-working-dir:
77
description: "Policy folder"
88
required: true
9-
type: string
109
outputs:
1110
policy-id:
1211
description: "Policy ID extract from the policy OCI URL"
@@ -35,16 +34,16 @@ runs:
3534
exit 1;
3635
fi
3736
38-
policy_ociUrl=$(yq -r '.annotations."io.kubewarden.policy.ociUrl"' '${{ inputs.policy-working-dir}}/metadata.yml')
39-
policy_version=$(yq -r '.annotations."io.kubewarden.policy.version"' '${{ inputs.policy-working-dir}}/metadata.yml')
37+
policy_ociUrl=$(yq -r '.annotations."io.kubewarden.policy.ociUrl"' '${{ inputs.policy-working-dir }}/metadata.yml')
38+
policy_version=$(yq -r '.annotations."io.kubewarden.policy.version"' '${{ inputs.policy-working-dir }}/metadata.yml')
4039
policy_id=${policy_ociUrl##*/}
4140
policy_basename=$(basename ${{inputs.policy-working-dir}})
4241
policy_language=""
4342
policy_rust_package=""
4443
4544
if [ -f '${{ inputs.policy-working-dir}}/Cargo.toml' ]; then
4645
policy_language="rust"
47-
policy_rust_package=$(sed -n 's,^name = \"\(.*\)\",\1,p' "${{ inputs.policy-working-dir}}/Cargo.toml")
46+
policy_rust_package=$(sed -n 's,^name = \"\(.*\)\",\1,p' "${{ inputs.policy-working-dir }}/Cargo.toml")
4847
if [ '$policy_rust_package' == "" ]; then
4948
echo 'cannot get rust policy ${{ inputs.policy-working-dir }} package name';
5049
exit 1;

.github/workflows/auto-labeler.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
fetch-depth: 0 # checkout all history to do git diff
2424
- name: 'Policy Matrix'
2525
id: policy-matrix
26-
uses: ./.github/actions/policy-matrix
26+
uses: ./.github/actions/calculate-policy-matrix
2727
auto_labeler:
2828
uses: ./.github/workflows/reusable-auto-labeler.yaml
2929
needs: calculate-policy-matrix

.github/workflows/ci.yaml

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,14 @@ jobs:
1313
calculate-policy-matrix:
1414
runs-on: ubuntu-latest
1515
outputs:
16-
policy_working_dirs: ${{ steps.calculate-policy-dirs.outputs.policy_working_dirs }}
16+
policy_working_dirs: ${{ steps.policy-matrix.outputs.policy_working_dirs }}
1717
steps:
1818
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
1919
with:
2020
fetch-depth: 0 # checkout all history to do git diff
21-
- name: calculate which policies need a CI job
22-
id: calculate-policy-dirs
23-
shell: bash
24-
run: |
25-
git remote -v
26-
27-
policies_working_dirs=($(find policies -maxdepth 2 -name Makefile -exec dirname '{}' \;))
28-
if [ "${{github.event_name}}" == "pull_request" ]; then
29-
# list only changes of files in `policies/`:
30-
git_files="$(git diff --no-color --find-renames --find-copies --name-only origin/${{ github.base_ref }} ${{ github.sha }} -- policies)"
31-
32-
# build policy_working_dirs:
33-
policies_working_dirs=($(echo "$git_files" | cut -d/ -f1,2 ))
34-
fi
35-
36-
declare -p policies_working_dirs # for debug
37-
policy_working_dirs=$(jq --compact-output --null-input '$ARGS.positional | map(select(. != "policies/Cargo.lock" and . != "policies/Cargo.toml" and . != "policies/go.mod" and . != "policies/go.sum")) | unique' --args -- "${policies_working_dirs[@]}")
38-
echo "policy_working_dirs=$policy_working_dirs"
39-
echo "policy_working_dirs=$policy_working_dirs" >> $GITHUB_OUTPUT
40-
21+
- name: 'Policy Matrix'
22+
id: policy-matrix
23+
uses: ./.github/actions/calculate-policy-matrix
4124
continuos-integration:
4225
uses: ./.github/workflows/reusable-ci.yaml
4326
needs: calculate-policy-matrix

.github/workflows/release-tag.yaml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
on:
2+
pull_request:
3+
types:
4+
- closed
5+
workflow_dispatch:
6+
inputs:
7+
policy-working-dir:
8+
description: "working directory under policies folder"
9+
required: true
10+
type: string
11+
12+
name: Tag and Release on PR Merge
13+
14+
jobs:
15+
calculate-policy-matrix:
16+
runs-on: ubuntu-latest
17+
outputs:
18+
policy_working_dirs: ${{ steps.calculate-policy-working-dirs.outputs.policy_working_dirs }}
19+
steps:
20+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
21+
with:
22+
fetch-depth: 0 # checkout all history to do git diff
23+
- name: 'Calculate which policies need a CI job'
24+
id: calculate-policy-working-dirs
25+
shell: bash
26+
run: |
27+
if [ "${{github.event_name}}" == "workflow_dispatch" ]; then
28+
dir_bash_array=("${{ inputs.policy-working-dir }}")
29+
else
30+
git remote -v
31+
# list only changes of files in `policies/`:
32+
# We compare base and head references to avoid detecting changes merged to close each other.
33+
# Otherwise, a job to tag the same policy could be triggered twice.
34+
git_files="$(git diff --no-color --find-renames --find-copies --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} -- policies)"
35+
36+
# build policy_working_dirs:
37+
dir_bash_array=($(echo "$git_files" | cut -d/ -f1,2 ))
38+
fi
39+
40+
declare -p dir_bash_array
41+
policy_working_dirs=$(jq --compact-output --null-input '$ARGS.positional | map(select(. != "policies/Cargo.lock" and . != "policies/Cargo.toml" and . != "policies/go.mod" and . != "policies/go.sum")) | unique' --args -- "${dir_bash_array[@]}")
42+
echo "policy_working_dirs=$policy_working_dirs"
43+
echo "policy_working_dirs=$policy_working_dirs" >> $GITHUB_OUTPUT
44+
release-tag:
45+
name: Tag and push, triggering release
46+
needs: calculate-policy-matrix
47+
if: >
48+
github.event.pull_request.merged == true &&
49+
contains(github.event.pull_request.labels.*.name, 'TRIGGER-RELEASE') ||
50+
github.event_name == 'workflow_dispatch'
51+
runs-on: ubuntu-latest
52+
concurrency:
53+
group: ${{ github.workflow }}-${{ matrix.policy-working-dir }}
54+
strategy:
55+
matrix:
56+
policy-working-dir: ${{ fromJSON(needs.calculate-policy-matrix.outputs.policy_working_dirs) }}
57+
steps:
58+
- name: Checkout repository
59+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
60+
with:
61+
fetch-depth: 0 # also checkout tags
62+
63+
- name: Get policy metadata
64+
id: policy-info
65+
uses: ./.github/actions/get-policy-metadata
66+
with:
67+
policy-working-dir: "${{ matrix.policy-working-dir }}"
68+
69+
- name: Extract version
70+
id: extract-version
71+
shell: bash
72+
run: |
73+
VERSION="${{ steps.policy-info.outputs.policy-basename }}/${{ steps.policy-info.outputs.policy-version }}"
74+
echo "VERSION=$VERSION" >> $GITHUB_ENV
75+
76+
- name: Configure Git author
77+
run: |
78+
git config user.name "Kubewarden bot"
79+
git config user.email "itpe-core-maintenance@suse.com"
80+
81+
- name: Create and push tag
82+
env:
83+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+
run: |
85+
git tag -a "$VERSION" -m "Release version $VERSION"
86+
git push origin "$VERSION"
87+
88+
- name: Trigger release workflow
89+
run: gh workflow run release.yaml --ref "$VERSION"
90+
env:
91+
GH_TOKEN: ${{ github.token }}

.github/workflows/release.yaml

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
on:
2+
workflow_dispatch:
3+
push:
4+
tags:
5+
- "*/v*"
6+
7+
name: Release policy
8+
9+
jobs:
10+
calculate-policy-from-tag:
11+
runs-on: ubuntu-latest
12+
outputs:
13+
policy-working-dir: ${{ steps.calculate-policy.outputs.policy_working_dir }}
14+
policy-version: ${{ steps.policy-info.outputs.policy-version }}
15+
policy-id: ${{ steps.policy-info.outputs.policy-id }}
16+
policy-name: ${{ steps.policy-info.outputs.policy-basename }}
17+
steps:
18+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
19+
- name: Calculate Policy
20+
id: calculate-policy
21+
shell: bash
22+
run: |
23+
policy_name=$( echo ${{ github.ref_name }} | sed 's/\(.*\)\/\(.*\)$/\1/' )
24+
policy_working_dir=$( find policies -type d -name "$policy_name")
25+
echo "policy_working_dir=$policy_working_dir" >> $GITHUB_OUTPUT
26+
- name: Get policy metadata
27+
id: policy-info
28+
uses: ./.github/actions/get-policy-metadata
29+
with:
30+
policy-working-dir: "${{ steps.calculate-policy.outputs.policy_working_dir }}"
31+
32+
ci:
33+
uses: ./.github/workflows/reusable-ci.yaml
34+
needs: calculate-policy-from-tag
35+
with:
36+
policy-working-dir: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
37+
38+
pre-release-checks:
39+
name: "Pre release checks"
40+
runs-on: ubuntu-latest
41+
needs: [calculate-policy-from-tag]
42+
steps:
43+
- name: Checkout code
44+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
45+
46+
- name: Check that `io.kubewarden.policy.version` annotation is up-to-date
47+
shell: bash
48+
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
49+
run: |
50+
VERSION=$(grep 'io.kubewarden.policy.version' metadata.yml | awk '{print $2}' | tr -d '"')
51+
if [ "$VERSION" != "${{ needs.calculate-policy-from-tag.outputs.policy-version }}" ]; then
52+
echo "The value of io.kubewarden.policy.version annotation is not in sync with the expected version: '${VERSION}' != '${{ needs.calculate-policy-from-tag.outputs.policy-version }}'"
53+
exit 1
54+
fi
55+
56+
release:
57+
runs-on: ubuntu-latest
58+
needs: [calculate-policy-from-tag, pre-release-checks, ci]
59+
permissions:
60+
# Required to create GH releases
61+
contents: write
62+
# Required to push to GHCR
63+
packages: write
64+
# Required by cosign keyless signing
65+
id-token: write
66+
steps:
67+
- name: Checkout code
68+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
69+
70+
- name: Install dependencies
71+
uses: ./.github/actions/install-dependencies
72+
73+
- name: Build Wasm module
74+
shell: bash
75+
run: make -C ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }} policy.wasm
76+
77+
- name: Annotate Wasm module
78+
shell: bash
79+
run: |
80+
make -C ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }} annotated-policy.wasm
81+
82+
- name: Generate the SBOM files
83+
shell: bash
84+
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
85+
run: |
86+
# SBOM files should have "sbom" in the name due the CLO monitor
87+
# https://clomonitor.io/docs/topics/checks/#software-bill-of-materials-sbom
88+
syft scan --output spdx-json=policy-sbom.spdx.json \
89+
--source-name $(yq '.annotations["io.kubewarden.policy.title"] + "-" + .annotations["io.kubewarden.policy.version"]' metadata.yml) \
90+
--source-version ${{ github.sha }} \
91+
-vv dir:.
92+
93+
- name: Sign BOM file
94+
shell: bash
95+
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
96+
run: |
97+
cosign sign-blob --yes \
98+
--bundle policy-sbom.spdx.jsonl.bundle.sigstore \
99+
policy-sbom.spdx.json
100+
101+
- name: Upload policy SBOM files
102+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
103+
with:
104+
name: policy-sbom
105+
path: |
106+
${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}/policy-sbom.spdx.json
107+
${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}/policy-sbom.spdx.jsonl.bundle.sigstore
108+
109+
- name: Login to GitHub Container Registry
110+
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
111+
with:
112+
registry: ghcr.io
113+
username: ${{ github.repository_owner }}
114+
password: ${{ secrets.GITHUB_TOKEN }}
115+
116+
- name: Publish Wasm policy artifact to OCI registry with the 'latest' tag
117+
shell: bash
118+
if: ${{ startsWith(github.ref, 'refs/heads/') }}
119+
run: |
120+
set -ex
121+
echo Pushing :latest policy to OCI container registry
122+
IMMUTABLE_REF=$(kwctl push -o json annotated-policy.wasm ghcr.io/${{ github.repository_owner }}/openplatform-kubewarden-policies/${{ needs.calculate-policy-from-tag.outputs.policy-id }}:latest | jq -r .immutable_ref)
123+
124+
echo Keyless signing of policy using cosign
125+
cosign sign --yes ${IMMUTABLE_REF}
126+
127+
- name: Publish Wasm policy artifact to OCI registry with the version tag and 'latest'
128+
shell: bash
129+
if: ${{ ! startsWith(github.ref, 'refs/heads/') }}
130+
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
131+
run: |
132+
set -ex
133+
export OCI_TAG="v${{ needs.calculate-policy-from-tag.outputs.policy-version }}"
134+
135+
echo Pushing tagged policy to OCI container registry
136+
IMMUTABLE_REF=$(kwctl push -o json annotated-policy.wasm ghcr.io/${{ github.repository_owner }}/openplatform-kubewarden-policies/${{ needs.calculate-policy-from-tag.outputs.policy-id }}:${OCI_TAG} | jq -r .immutable_ref)
137+
138+
echo Keyless signing of policy using cosign
139+
cosign sign --yes ${IMMUTABLE_REF}
140+
141+
- name: Create release
142+
id: create-release
143+
uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
144+
with:
145+
config-name: "release-drafter-${{ needs.calculate-policy-from-tag.outputs.policy-name }}.yml"
146+
disable-autolabeler: true
147+
prerelease: ${{ contains(needs.calculate-policy-from-tag.outputs.policy-version, '-alpha') || contains(needs.calculate-policy-from-tag.outputs.policy-version, '-beta') || contains(needs.calculate-policy-from-tag.outputs.policy-version, '-rc') }}
148+
env:
149+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
150+
151+
- name: Upload release assets
152+
if: ${{ ! startsWith(github.ref, 'refs/heads/') }}
153+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
154+
env:
155+
POLICY_WORKING_DIR: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
156+
RELEASE_ID: ${{ steps.create-release.outputs.id }}
157+
with:
158+
script: |
159+
let fs = require('fs');
160+
let path = require('path');
161+
let workingDir = process.env.POLICY_WORKING_DIR || '.';
162+
163+
let files = [
164+
`${workingDir}/policy.wasm`,
165+
`${workingDir}/policy-sbom.spdx.json`,
166+
`${workingDir}/policy-sbom.spdx.jsonl.bundle.sigstore`,
167+
]
168+
const {RELEASE_ID} = process.env
169+
170+
for (const file of files) {
171+
let file_data = fs.readFileSync(file);
172+
173+
let response = await github.rest.repos.uploadReleaseAsset({
174+
owner: context.repo.owner,
175+
repo: context.repo.repo,
176+
release_id: `${RELEASE_ID}`,
177+
name: path.basename(file),
178+
data: file_data,
179+
});
180+
}
181+
- name: Publish release
182+
# if we are on a single repo, we obtain the last draft release as it contains the changelog
183+
# and edit it by adding the artifacts. Then we mark the release as latest
184+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
185+
env:
186+
RELEASE_ID: ${{ steps.create-release.outputs.id }}
187+
with:
188+
script: |
189+
const {RELEASE_ID} = process.env
190+
const TAG_NAME = "${{ github.ref_name }}";
191+
isPreRelease = ${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') }}
192+
github.rest.repos.updateRelease({
193+
owner: context.repo.owner,
194+
repo: context.repo.repo,
195+
release_id: `${RELEASE_ID}`,
196+
draft: false,
197+
tag_name: TAG_NAME,
198+
name: TAG_NAME,
199+
prerelease: isPreRelease,
200+
make_latest: !isPreRelease
201+
});

policies/harvester-pci-devices/metadata.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ annotations:
1919
io.kubewarden.policy.author: "ITPE Core Team <itpe-core-maintenance@suse.com>"
2020
io.kubewarden.policy.url: https://github.github.com/SUSE/openplatform-kubewarden-policies
2121
io.kubewarden.policy.source: https://github.github.com/SUSE/openplatform-kubewarden-policies
22+
io.kubewarden.policy.ociUrl: ghcr.io/suse/openplatform-kubewarden-policies/harvester-pci-devices
2223
# The next two annotations are used in the policy report generated by the
2324
# Audit scanner. Severity indicates policy check result criticality and
2425
# Category indicates policy category. See more here at docs.kubewarden.io

policies/harvester-restricted-network-vm/metadata.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ annotations:
1919
io.kubewarden.policy.author: "ITPE Core Team <itpe-core-maintenance@suse.com>"
2020
io.kubewarden.policy.url: https://github.github.com/SUSE/openplatform-kubewarden-policies
2121
io.kubewarden.policy.source: https://github.github.com/SUSE/openplatform-kubewarden-policies
22+
io.kubewarden.policy.ociUrl: ghcr.io/suse/openplatform-kubewarden-policies/harvester-restricted-network-vm
2223
# The next two annotations are used in the policy report generated by the
2324
# Audit scanner. Severity indicates policy check result criticality and
2425
# Category indicates policy category. See more here at docs.kubewarden.io

0 commit comments

Comments
 (0)