Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ runs:
git remote -v

policies_working_dirs=($(find policies -maxdepth 2 -name Makefile -exec dirname '{}' \;))

if [ "${{github.event_name}}" == "pull_request" ]; then
# list only changes of files in `policies/`:
git_files="$(git diff --no-color --find-renames --find-copies --name-only origin/${{ github.base_ref }} ${{ github.sha }} -- policies)"
Expand All @@ -22,7 +23,7 @@ runs:
policies_working_dirs=($(echo "$git_files" | cut -d/ -f1,2 ))
fi

declare -p policies_working_dirs # for debug
declare -p policies_working_dirs
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[@]}")
echo "policy_working_dirs=$policy_working_dirs"
echo "policy_working_dirs=$policy_working_dirs" >> $GITHUB_OUTPUT
7 changes: 3 additions & 4 deletions .github/actions/get-policy-metadata/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ inputs:
policy-working-dir:
description: "Policy folder"
required: true
type: string
outputs:
policy-id:
description: "Policy ID extract from the policy OCI URL"
Expand Down Expand Up @@ -35,16 +34,16 @@ runs:
exit 1;
fi

policy_ociUrl=$(yq -r '.annotations."io.kubewarden.policy.ociUrl"' '${{ inputs.policy-working-dir}}/metadata.yml')
policy_version=$(yq -r '.annotations."io.kubewarden.policy.version"' '${{ inputs.policy-working-dir}}/metadata.yml')
policy_ociUrl=$(yq -r '.annotations."io.kubewarden.policy.ociUrl"' '${{ inputs.policy-working-dir }}/metadata.yml')
policy_version=$(yq -r '.annotations."io.kubewarden.policy.version"' '${{ inputs.policy-working-dir }}/metadata.yml')
policy_id=${policy_ociUrl##*/}
policy_basename=$(basename ${{inputs.policy-working-dir}})
policy_language=""
policy_rust_package=""

if [ -f '${{ inputs.policy-working-dir}}/Cargo.toml' ]; then
policy_language="rust"
policy_rust_package=$(sed -n 's,^name = \"\(.*\)\",\1,p' "${{ inputs.policy-working-dir}}/Cargo.toml")
policy_rust_package=$(sed -n 's,^name = \"\(.*\)\",\1,p' "${{ inputs.policy-working-dir }}/Cargo.toml")
if [ '$policy_rust_package' == "" ]; then
echo 'cannot get rust policy ${{ inputs.policy-working-dir }} package name';
exit 1;
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/auto-labeler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
fetch-depth: 0 # checkout all history to do git diff
- name: 'Policy Matrix'
id: policy-matrix
uses: ./.github/actions/policy-matrix
uses: ./.github/actions/calculate-policy-matrix
auto_labeler:
uses: ./.github/workflows/reusable-auto-labeler.yaml
needs: calculate-policy-matrix
Expand Down
25 changes: 4 additions & 21 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,14 @@ jobs:
calculate-policy-matrix:
runs-on: ubuntu-latest
outputs:
policy_working_dirs: ${{ steps.calculate-policy-dirs.outputs.policy_working_dirs }}
policy_working_dirs: ${{ steps.policy-matrix.outputs.policy_working_dirs }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0 # checkout all history to do git diff
- name: calculate which policies need a CI job
id: calculate-policy-dirs
shell: bash
run: |
git remote -v

policies_working_dirs=($(find policies -maxdepth 2 -name Makefile -exec dirname '{}' \;))
if [ "${{github.event_name}}" == "pull_request" ]; then
# list only changes of files in `policies/`:
git_files="$(git diff --no-color --find-renames --find-copies --name-only origin/${{ github.base_ref }} ${{ github.sha }} -- policies)"

# build policy_working_dirs:
policies_working_dirs=($(echo "$git_files" | cut -d/ -f1,2 ))
fi

declare -p policies_working_dirs # for debug
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[@]}")
echo "policy_working_dirs=$policy_working_dirs"
echo "policy_working_dirs=$policy_working_dirs" >> $GITHUB_OUTPUT

- name: 'Policy Matrix'
id: policy-matrix
uses: ./.github/actions/calculate-policy-matrix
continuos-integration:
uses: ./.github/workflows/reusable-ci.yaml
needs: calculate-policy-matrix
Expand Down
91 changes: 91 additions & 0 deletions .github/workflows/release-tag.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
on:
pull_request:
types:
- closed
workflow_dispatch:
inputs:
policy-working-dir:
description: "working directory under policies folder"
required: true
type: string

name: Tag and Release on PR Merge

jobs:
calculate-policy-matrix:
runs-on: ubuntu-latest
outputs:
policy_working_dirs: ${{ steps.calculate-policy-working-dirs.outputs.policy_working_dirs }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0 # checkout all history to do git diff
- name: 'Calculate which policies need a CI job'
id: calculate-policy-working-dirs
shell: bash
run: |
if [ "${{github.event_name}}" == "workflow_dispatch" ]; then
dir_bash_array=("${{ inputs.policy-working-dir }}")
else
git remote -v
# list only changes of files in `policies/`:
# We compare base and head references to avoid detecting changes merged to close each other.
# Otherwise, a job to tag the same policy could be triggered twice.
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)"

# build policy_working_dirs:
dir_bash_array=($(echo "$git_files" | cut -d/ -f1,2 ))
fi

declare -p dir_bash_array
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[@]}")
echo "policy_working_dirs=$policy_working_dirs"
echo "policy_working_dirs=$policy_working_dirs" >> $GITHUB_OUTPUT
release-tag:
name: Tag and push, triggering release
needs: calculate-policy-matrix
if: >
github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'TRIGGER-RELEASE') ||
github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ matrix.policy-working-dir }}
strategy:
matrix:
policy-working-dir: ${{ fromJSON(needs.calculate-policy-matrix.outputs.policy_working_dirs) }}
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0 # also checkout tags

- name: Get policy metadata
id: policy-info
uses: ./.github/actions/get-policy-metadata
with:
policy-working-dir: "${{ matrix.policy-working-dir }}"

- name: Extract version
id: extract-version
shell: bash
run: |
VERSION="${{ steps.policy-info.outputs.policy-basename }}/v${{ steps.policy-info.outputs.policy-version }}"
echo "VERSION=$VERSION" >> $GITHUB_ENV

- name: Configure Git author
run: |
git config user.name "Kubewarden bot"
git config user.email "itpe-core-maintenance@suse.com"

- name: Create and push tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git tag -a "$VERSION" -m "Release version $VERSION"
git push origin "$VERSION"

- name: Trigger release workflow
run: gh workflow run release.yaml --ref "$VERSION"
env:
GH_TOKEN: ${{ github.token }}
201 changes: 201 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
on:
workflow_dispatch:
push:
tags:
- "*/v*"

name: Release policy

jobs:
calculate-policy-from-tag:
runs-on: ubuntu-latest
outputs:
policy-working-dir: ${{ steps.calculate-policy.outputs.policy_working_dir }}
policy-version: ${{ steps.policy-info.outputs.policy-version }}
policy-id: ${{ steps.policy-info.outputs.policy-id }}
policy-name: ${{ steps.policy-info.outputs.policy-basename }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Calculate Policy
id: calculate-policy
shell: bash
run: |
policy_name=$( echo ${{ github.ref_name }} | sed 's/\(.*\)\/\(.*\)$/\1/' )
policy_working_dir=$( find policies -type d -name "$policy_name")
echo "policy_working_dir=$policy_working_dir" >> $GITHUB_OUTPUT
- name: Get policy metadata
id: policy-info
uses: ./.github/actions/get-policy-metadata
with:
policy-working-dir: "${{ steps.calculate-policy.outputs.policy_working_dir }}"

ci:
uses: ./.github/workflows/reusable-ci.yaml
needs: calculate-policy-from-tag
with:
policy-working-dir: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}

pre-release-checks:
name: "Pre release checks"
runs-on: ubuntu-latest
needs: [calculate-policy-from-tag]
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Check that `io.kubewarden.policy.version` annotation is up-to-date
shell: bash
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
run: |
VERSION=$(grep 'io.kubewarden.policy.version' metadata.yml | awk '{print $2}' | tr -d '"')
if [ "$VERSION" != "${{ needs.calculate-policy-from-tag.outputs.policy-version }}" ]; then
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 }}'"
exit 1
fi

release:
runs-on: ubuntu-latest
needs: [calculate-policy-from-tag, pre-release-checks, ci]
permissions:
# Required to create GH releases
contents: write
# Required to push to GHCR
packages: write
# Required by cosign keyless signing
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Install dependencies
uses: ./.github/actions/install-dependencies

- name: Build Wasm module
shell: bash
run: make -C ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }} policy.wasm

- name: Annotate Wasm module
shell: bash
run: |
make -C ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }} annotated-policy.wasm

- name: Generate the SBOM files
shell: bash
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
run: |
# SBOM files should have "sbom" in the name due the CLO monitor
# https://clomonitor.io/docs/topics/checks/#software-bill-of-materials-sbom
syft scan --output spdx-json=policy-sbom.spdx.json \
--source-name $(yq '.annotations["io.kubewarden.policy.title"] + "-" + .annotations["io.kubewarden.policy.version"]' metadata.yml) \
--source-version ${{ github.sha }} \
-vv dir:.

- name: Sign BOM file
shell: bash
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
run: |
cosign sign-blob --yes \
--bundle policy-sbom.spdx.jsonl.bundle.sigstore \
policy-sbom.spdx.json

- name: Upload policy SBOM files
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: policy-sbom
path: |
${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}/policy-sbom.spdx.json
${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}/policy-sbom.spdx.jsonl.bundle.sigstore

- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Publish Wasm policy artifact to OCI registry with the 'latest' tag
shell: bash
if: ${{ startsWith(github.ref, 'refs/heads/') }}
run: |
set -ex
echo Pushing :latest policy to OCI container registry
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)

echo Keyless signing of policy using cosign
cosign sign --yes ${IMMUTABLE_REF}

- name: Publish Wasm policy artifact to OCI registry with the version tag and 'latest'
shell: bash
if: ${{ ! startsWith(github.ref, 'refs/heads/') }}
working-directory: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
run: |
set -ex
export OCI_TAG="v${{ needs.calculate-policy-from-tag.outputs.policy-version }}"

echo Pushing tagged policy to OCI container registry
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)

echo Keyless signing of policy using cosign
cosign sign --yes ${IMMUTABLE_REF}

- name: Create release
id: create-release
uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
with:
config-name: "release-drafter-${{ needs.calculate-policy-from-tag.outputs.policy-name }}.yml"
disable-autolabeler: true
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') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload release assets
if: ${{ ! startsWith(github.ref, 'refs/heads/') }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
POLICY_WORKING_DIR: ${{ needs.calculate-policy-from-tag.outputs.policy-working-dir }}
RELEASE_ID: ${{ steps.create-release.outputs.id }}
with:
script: |
let fs = require('fs');
let path = require('path');
let workingDir = process.env.POLICY_WORKING_DIR || '.';

let files = [
`${workingDir}/policy.wasm`,
`${workingDir}/policy-sbom.spdx.json`,
`${workingDir}/policy-sbom.spdx.jsonl.bundle.sigstore`,
]
const {RELEASE_ID} = process.env

for (const file of files) {
let file_data = fs.readFileSync(file);

let response = await github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: `${RELEASE_ID}`,
name: path.basename(file),
data: file_data,
});
}
- name: Publish release
# if we are on a single repo, we obtain the last draft release as it contains the changelog
# and edit it by adding the artifacts. Then we mark the release as latest
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
RELEASE_ID: ${{ steps.create-release.outputs.id }}
with:
script: |
const {RELEASE_ID} = process.env
const TAG_NAME = "${{ github.ref_name }}";
isPreRelease = ${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') }}
github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: `${RELEASE_ID}`,
draft: false,
tag_name: TAG_NAME,
name: TAG_NAME,
prerelease: isPreRelease,
make_latest: !isPreRelease
});