Skip to content

Release

Release #436

Workflow file for this run

name: Release
on:
release:
types:
- created
schedule:
- cron: '0 1 * * 1-5' # 1 AM UTC is 5 PM PST/ 6 PM PDT
workflow_dispatch:
jobs:
publish-image:
permissions:
contents: write # Used to upload assets
packages: write # Used to push images to `ghcr.io`
id-token: write # Needed to create an OIDC token for keyless signing
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
outputs:
image-digest: ${{ steps.image.outputs.digest }}
kargo-repo: ${{ steps.repo.outputs.repo }}
unstable-version: ${{ steps.unstable-version.outputs.unstable-version }}
steps:
- name: Determine which repository to use for images
id: repo
run: |
REPO=ghcr.io/akuity/kargo
if ${{ github.event_name != 'release' }}
then
REPO=ghcr.io/akuity/kargo-unstable
fi
echo "Repository is set to: $REPO"
echo "repo=$REPO" >> $GITHUB_OUTPUT
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
with:
go-version: '1.23.0'
- name: Set version for unstable builds
id: unstable-version
run: |
set -xue
# Once Kargo goes to v2, we need to replace github.com/akuity/kargo with github.com/akuity/kargo/v2 on the next line
LATEST_VERSION=$(go list -m -versions github.com/akuity/kargo | awk '{print $NF}' | awk -F "." '{print $1"."$2".0"}')
NEW_VERSION=$(awk 'BEGIN {FS=OFS="."} {$2++; print}' <<< "${LATEST_VERSION}")
echo "unstable-version=${NEW_VERSION}-unstable-$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
with:
driver-opts: network=host
- name: Install Cosign
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
with:
cosign-release: 'v2.2.1' # optional
- name: Login to GHCR
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.repo.outputs.repo }}
flavor: latest=false
tags: |
type=semver,pattern={{raw}}
type=raw,value=${{ steps.unstable-version.outputs.unstable-version }},enable=${{ github.event_name != 'release'}}
- name: Build base image
run: |
BASE_IMAGE=localhost:5000/kargo-base make build-base-image
docker push localhost:5000/kargo-base:latest-arm64
docker push localhost:5000/kargo-base:latest-amd64
- name: Build and push final image
id: image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
build-args: |
BASE_IMAGE=localhost:5000/kargo-base
VERSION=${{ github.ref_name }}
GIT_COMMIT=${{ github.sha }}
GIT_TREE_STATE=clean
tags: ${{ steps.meta.outputs.tags }}
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
sbom: false
- name: Sign image
run: |
cosign sign \
-a "repo=${{ github.repository }}" \
-a "workflow=${{ github.workflow }}" \
-a "sha=${{ github.sha }}" \
--yes \
${{ steps.repo.outputs.repo}}@${{ steps.image.outputs.digest}}
- name: Publish SBOM
if: github.event_name == 'release'
uses: anchore/sbom-action@v0
with:
image: ${{ steps.meta.outputs.tags }}
kargo-image-provenance:
needs:
- publish-image
permissions:
actions: read # for detecting the Github Actions environment.
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues)
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: ${{ needs.publish-image.outputs.kargo-repo }}
digest: ${{ needs.publish-image.outputs.image-digest }}
secrets:
registry-username: ${{ github.actor }}
registry-password: ${{ secrets.GITHUB_TOKEN }}
publish-charts:
needs: publish-image
runs-on: ubuntu-latest
steps:
- name: Determine which repository to use
id: chart_repo
run: |
REPO=ghcr.io/akuity/kargo-charts
if ${{ github.event_name != 'release' }}
then
REPO=ghcr.io/akuity/kargo-charts-unstable
fi
echo "Repository is set to: $REPO"
echo "chart_repo=$REPO" >> $GITHUB_OUTPUT
- name: Determine Version
id: version
run: |
VERSION=${{ github.ref_name }}
if ${{ github.event_name != 'release' }}
then
VERSION=${{ needs.publish-image.outputs.unstable-version }}
fi
echo "VERSION is set to: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: '3.12.3'
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Publish chart
env:
HELM_EXPERIMENTAL_OCI: '1'
KARGO_CHARTS_REPO: ${{ steps.chart_repo.outputs.chart_repo }}
VERSION: ${{ steps.version.outputs.version }}
run: |
CHART_VERSION=$(echo $VERSION | cut -c 2-)
cd charts/kargo
helm dep up
helm package . --version ${CHART_VERSION} --app-version ${VERSION}
helm push kargo-${CHART_VERSION}.tgz oci://${KARGO_CHARTS_REPO}
publish-cli:
if: github.event_name == 'release'
runs-on: ubuntu-latest
container:
image: golang:1.23.4-bookworm
strategy:
matrix:
os: [linux, darwin, windows]
arch: [amd64, arm64]
outputs:
hash-linux-amd64: ${{ steps.hash.outputs.hash-linux-amd64 }}
hash-linux-arm64: ${{ steps.hash.outputs.hash-linux-arm64 }}
hash-darwin-amd64: ${{ steps.hash.outputs.hash-darwin-amd64 }}
hash-darwin-arm64: ${{ steps.hash.outputs.hash-darwin-arm64 }}
hash-windows-amd64: ${{ steps.hash.outputs.hash-windows-amd64 }}
hash-windows-arm64: ${{ steps.hash.outputs.hash-windows-arm64 }}
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: /go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Install pnpm
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
with:
package_json_file: ui/package.json
- name: Install nodejs
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: "22.8.0"
cache: "pnpm"
cache-dependency-path: "**/pnpm-lock.yaml"
- name: Build UI
env:
VERSION: ${{ github.ref_name }}
working-directory: ./ui
run: |
pnpm install
NODE_ENV=production pnpm run build
rm -rf ../internal/api/ui
mv build ../internal/api/ui
- name: Build CLI
env:
GOFLAGS: -buildvcs=false
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
VERSION: ${{ github.ref_name }}
GIT_COMMIT: ${{ github.sha }}
GIT_TREE_STATE: clean
run: make build-cli
- name: Publish CLI
uses: svenstaro/upload-release-action@v2
with:
file: bin/*
file_glob: true
repo_token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate subject
id: hash
run: |
echo "hash-${{ matrix.os }}-${{ matrix.arch }}=$(sha256sum bin/kargo* | awk -F 'bin/' '{print $1 $2}'| base64 -w0)" >> "$GITHUB_OUTPUT"
publish-unstable-cli:
needs: publish-image
permissions:
id-token: write
contents: read
if: github.event_name != 'release'
runs-on: ubuntu-latest
container:
image: golang:1.23.4-bookworm
strategy:
matrix:
os: [linux, darwin, windows]
arch: [amd64, arm64]
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: /go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Install pnpm
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
with:
package_json_file: ui/package.json
- name: Install nodejs
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: "22.8.0"
cache: "pnpm"
cache-dependency-path: "**/pnpm-lock.yaml"
- name: Build UI
env:
VERSION: ${{ github.ref_name }}
working-directory: ./ui
run: |
pnpm install
NODE_ENV=production pnpm run build
rm -rf ../internal/api/ui
mv build ../internal/api/ui
- name: Build CLI
env:
GOFLAGS: -buildvcs=false
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
VERSION: ${{ needs.publish-image.outputs.unstable-version }}
GIT_COMMIT: ${{ github.sha }}
GIT_TREE_STATE: clean
run: make build-nightly-cli
- name: Install awscli
run: |
apt update && apt install awscli -y
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE }}
aws-region: us-west-2
- name: Push binaries
env:
CF_DISTRIBUTION_ID: ${{ secrets.CF_DISTRIBUTION_ID }}
VERSION: ${{ needs.publish-image.outputs.unstable-version }}
run: |
aws s3 sync "./bin/kargo-cli/${VERSION}/${{ matrix.os }}/${{ matrix.arch }}" "s3://kargo-release/kargo-cli/${VERSION}/${{ matrix.os }}/${{ matrix.arch }}"
printf "${VERSION}" > ./bin/kargo-cli/unstable.txt
aws s3 cp ./bin/kargo-cli/unstable.txt s3://kargo-release/kargo-cli/unstable.txt
aws cloudfront create-invalidation \
--distribution-id="${CF_DISTRIBUTION_ID}" \
--paths "/kargo-cli/unstable.txt"
combine_hashes:
needs: [publish-cli]
if: github.event_name == 'release'
runs-on: ubuntu-latest
outputs:
hashes: ${{ steps.hashes.outputs.hashes }}
env:
HASHES: ${{ toJSON(needs.publish-cli.outputs) }}
steps:
- id: hashes
run: |
echo "$HASHES" | jq -r '.[] | @base64d' | sed "/^$/d" > hashes.txt
echo "hashes=$(cat hashes.txt | base64 -w0)" >> "$GITHUB_OUTPUT"
provenance:
needs: [combine_hashes]
if: github.event_name == 'release'
permissions:
actions: read # To read the workflow path.
id-token: write # To sign the provenance.
contents: write # To add assets to a release.
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
base64-subjects: "${{ needs.combine_hashes.outputs.hashes }}"
upload-assets: true # Optional: Upload to a new release
provenance-name: kargo-cli.intoto.jsonl