Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: update ci for release #5066

Merged
merged 1 commit into from
Nov 10, 2023
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
20 changes: 20 additions & 0 deletions .github/actions/e2e/install-helm/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: InstallHelm
description: 'Installs helm'
inputs:
version:
description: "Version of Helm to install"
required: true
runs:
using: "composite"
steps:
- name: install helm
shell: bash
run: |
TEMPDIR=$(mktemp -d)
curl -fsSL -o "${TEMPDIR}/get_helm.sh" https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 "${TEMPDIR}/get_helm.sh"
"${TEMPDIR}/get_helm.sh" --version ${{ inputs.version }}
- name: install helm-diff
shell: bash
run: |
helm plugin install https://github.com/databus23/helm-diff || true
35 changes: 0 additions & 35 deletions .github/workflows/release-trigger.yaml

This file was deleted.

56 changes: 26 additions & 30 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,61 +1,57 @@
name: Release
on:
workflow_run:
workflows: [ReleaseTrigger]
types: [completed]
push:
tags: [ 'v*.*.*' ]
permissions:
id-token: write
pull-requests: write
contents: write
id-token: write # aws-actions/[email protected]
contents: write # marvinpinto/action-automatic-releases@latest
pull-requests: write # name: Create PR
jobs:
release:
if: github.event.workflow_run.conclusion == 'success' && contains(fromJson('["push"]'), github.event.workflow_run.event)
if: github.repository == 'aws/karpenter'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/download-artifact
- run: |
tag=$(head -n 1 /tmp/artifacts/metadata.txt)
tag_commit=$(tail -n 1 /tmp/artifacts/metadata.txt)
echo "TAG_COMMIT=$tag_commit" >> $GITHUB_ENV
echo "TAG=$tag" >> $GITHUB_ENV
- name: Checkout the repository out again at the given SHA from the artifact
uses: actions/checkout@v3
- name: Create GitHub Release
uses: 'marvinpinto/action-automatic-releases@latest'
with:
fetch-depth: 0
ref: ${{ env.TAG_COMMIT }}
repo_token: '${{ secrets.GITHUB_TOKEN }}'
prerelease: false
- id: tag
run: |
TAG="$(git describe --tags --exact-match)"
echo TAG="${TAG}" >> "$GITHUB_OUTPUT"
- uses: ./.github/actions/install-deps
- uses: ./.github/actions/authenticate-aws
- uses: ./.github/actions/authenticate-ghcr
- uses: ./.github/actions/e2e/install-helm
with:
version: v3.12.3 # Pinned to this version since v3.13.0 has issues with pushing to public ECR: https://github.com/helm/helm/issues/12442
- uses: aws-actions/[email protected]
with:
actor: ${{ github.actor }}
secret: ${{ secrets.GITHUB_TOKEN }}
role-to-assume: 'arn:aws:iam::${{ vars.ECR_ACCOUNT_ID }}:role/${{ vars.ECR_RELEASE_ROLE_NAME }}'
aws-region: ${{ vars.ECR_REGION }}
- run: make release
- run: make docgen
- name: Autogenerate and commit files for PR for major and minor releases only
if: endsWith(env.TAG ,'.0')
run: make prepare-website
- run: make prepare-website
- run: make stable-release-pr
if: env.TAG != 'no tag'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPO: ${{ github.repository }}
- name: Create PR
if: env.TAG != 'no tag'
if: steps.tag.outputs.TAG != 'no tag'
uses: actions/github-script@v6
with:
script: |
const { repo, owner } = context.repo;
const result = await github.rest.pulls.create({
title: 'chore: Release ${{ env.TAG }}',
title: 'chore: Release ${{ steps.tag.outputs.TAG }}',
owner,
repo,
head: 'release-${{ env.TAG }}',
head: 'release-${{ steps.tag.outputs.TAG }}',
base: 'main',
body: [
'Stable Release Changes for ${{ env.TAG }}.',
'Stable Release Changes for ${{ steps.tag.outputs.TAG }}.',
'Please disregard this PR if it is for a patch release.',
'Please remove the branch after merging.',
'This PR is generated by [StableRelease](https://github.com/aws/karpenter/actions/workflows/stable-release.yml).'
Expand Down
120 changes: 64 additions & 56 deletions hack/release/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ config(){
RELEASE_REPO_ECR=${RELEASE_REPO_ECR:-public.ecr.aws/${ECR_GALLERY_NAME}/}
RELEASE_REPO_GH=${RELEASE_REPO_GH:-ghcr.io/${GITHUB_ACCOUNT}/karpenter}

MAIN_GITHUB_ACCOUNT="aws"
PRIVATE_PULL_THROUGH_HOST="${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com"
SNS_TOPIC_ARN="arn:aws:sns:us-east-1:${AWS_ACCOUNT_ID}:KarpenterReleases"
PRIVATE_HOST="${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com"
SNAPSHOT_REPO_ECR=${SNAPSHOT_REPO_ECR:-${PRIVATE_HOST}/karpenter/snapshot/}

CURRENT_MAJOR_VERSION="0"
RELEASE_PLATFORM="--platform=linux/amd64,linux/arm64"

MAIN_GITHUB_ACCOUNT="aws"
RELEASE_TYPE_STABLE="stable"
RELEASE_TYPE_SNAPSHOT="snapshot"
}
Expand All @@ -27,26 +28,35 @@ versionData(){
RELEASE_VERSION_MINOR="${VERSION#*.}"
RELEASE_VERSION_MINOR="${RELEASE_VERSION_MINOR%.*}"
RELEASE_VERSION_PATCH="${VERSION##*.}"
RELEASE_MINOR_VERSION="v${RELEASE_VERSION_MAJOR}.${RELEASE_VERSION_MINOR}"
}

release() {
snapshot() {
RELEASE_VERSION=$1
echo "Release Type: $(releaseType "${RELEASE_VERSION}")
echo "Release Type: snapshot
Release Version: ${RELEASE_VERSION}
Commit: $(git rev-parse HEAD)
Helm Chart Version $(helmChartVersion $RELEASE_VERSION)"

PR_NUMBER=${GH_PR_NUMBER:-}
if [ "${GH_PR_NUMBER+defined}" != defined ]; then
PR_NUMBER="none"
fi
authenticatePrivateRepo
buildImages ${SNAPSHOT_REPO_ECR}
cosignImages
publishHelmChart "karpenter" "${RELEASE_VERSION}" "${SNAPSHOT_REPO_ECR}"
publishHelmChart "karpenter-crd" "${RELEASE_VERSION}" "${SNAPSHOT_REPO_ECR}"
}

release() {
RELEASE_VERSION=$1
echo "Release Type: stable
Release Version: ${RELEASE_VERSION}
Commit: $(git rev-parse HEAD)
Helm Chart Version $(helmChartVersion $RELEASE_VERSION)"

authenticate
buildImages
buildImages ${RELEASE_REPO_ECR}
cosignImages
publishHelmChart "karpenter" "${RELEASE_VERSION}" "${RELEASE_REPO_ECR}"
publishHelmChart "karpenter-crd" "${RELEASE_VERSION}" "${RELEASE_REPO_ECR}"
notifyRelease "$RELEASE_VERSION" $PR_NUMBER
pullPrivateReplica "$RELEASE_VERSION"
}

Expand All @@ -55,11 +65,14 @@ authenticate() {
}

authenticatePrivateRepo() {
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${PRIVATE_PULL_THROUGH_HOST}
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${PRIVATE_HOST}
}

buildImages() {
CONTROLLER_IMG=$(GOFLAGS=${GOFLAGS} KO_DOCKER_REPO=${RELEASE_REPO_ECR} ko publish -B -t "${RELEASE_VERSION}" "${RELEASE_PLATFORM}" ./cmd/controller)
RELEASE_REPO=$1
# Set the SOURCE_DATE_EPOCH and KO_DATA_DATE_EPOCH values for reproducable builds with timestamps
# https://ko.build/advanced/faq/
CONTROLLER_IMG=$(GOFLAGS=${GOFLAGS} SOURCE_DATE_EPOCH=$(git log -1 --format='%ct') KO_DATA_DATE_EPOCH=$(git log -1 --format='%ct') KO_DOCKER_REPO=${RELEASE_REPO} ko publish -B -t "${RELEASE_VERSION}" "${RELEASE_PLATFORM}" ./cmd/controller)
HELM_CHART_VERSION=$(helmChartVersion "$RELEASE_VERSION")
IMG_REPOSITORY=$(echo "$CONTROLLER_IMG" | cut -d "@" -f 1 | cut -d ":" -f 1)
IMG_TAG=$(echo "$CONTROLLER_IMG" | cut -d "@" -f 1 | cut -d ":" -f 2 -s)
Expand All @@ -85,23 +98,21 @@ releaseType(){

helmChartVersion(){
RELEASE_VERSION=$1
if [[ $(releaseType $RELEASE_VERSION) == $RELEASE_TYPE_STABLE ]]; then
echo $RELEASE_VERSION
if [[ $(releaseType "$RELEASE_VERSION") == "$RELEASE_TYPE_STABLE" ]]; then
echo "$RELEASE_VERSION"
fi

if [[ $(releaseType $RELEASE_VERSION) == $RELEASE_TYPE_SNAPSHOT ]]; then
if [[ $(releaseType "$RELEASE_VERSION") == "$RELEASE_TYPE_SNAPSHOT" ]]; then
echo "v${CURRENT_MAJOR_VERSION}-${RELEASE_VERSION}"
fi
}

buildDate(){
# TODO restore https://reproducible-builds.org/docs/source-date-epoch/
# Set the SOURCE_DATE_EPOCH and KO_DATA_DATE_EPOCH values for reproducable builds with timestamps
# https://ko.build/advanced/faq/
DATE_FMT="+%Y-%m-%dT%H:%M:%SZ"
if [ -z "${SOURCE_DATE_EPOCH-}" ]; then
echo $(date -u ${DATE_FMT})
else
echo$(date -u -d "${SOURCE_DATE_EPOCH}" "${DATE_FMT}" 2>/dev/null || date -u -r "${SOURCE_DATE_EPOCH}" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)")
fi
SOURCE_DATE_EPOCH=$(git log -1 --format='%ct')
echo "$(date -u -r "${SOURCE_DATE_EPOCH}" $DATE_FMT 2>/dev/null)"
}

cosignImages() {
Expand All @@ -112,22 +123,10 @@ cosignImages() {
"${CONTROLLER_IMG}"
}

notifyRelease() {
RELEASE_VERSION=$1
PR_NUMBER=$2
RELEASE_TYPE=$(releaseType $RELEASE_VERSION)
LAST_STABLE_RELEASE_TAG=$(git describe --tags --abbrev=0)
MESSAGE="{\"releaseType\":\"${RELEASE_TYPE}\",\"releaseIdentifier\":\"${RELEASE_VERSION}\",\"prNumber\":\"${PR_NUMBER}\",\"githubAccount\":\"${GITHUB_ACCOUNT}\",\"lastStableReleaseTag\":\"${LAST_STABLE_RELEASE_TAG}\"}"
aws sns publish \
--topic-arn ${SNS_TOPIC_ARN} \
--message ${MESSAGE} \
--no-cli-pager
}

pullPrivateReplica(){
authenticatePrivateRepo
RELEASE_IDENTIFIER=$1
PULL_THROUGH_CACHE_PATH="${PRIVATE_PULL_THROUGH_HOST}/ecr-public/${ECR_GALLERY_NAME}/"
PULL_THROUGH_CACHE_PATH="${PRIVATE_HOST}/ecr-public/${ECR_GALLERY_NAME}/"
HELM_CHART_VERSION=$(helmChartVersion "$RELEASE_VERSION")
docker pull "${PULL_THROUGH_CACHE_PATH}controller:${RELEASE_IDENTIFIER}"
helm pull "oci://${PULL_THROUGH_CACHE_PATH}karpenter" --version "${HELM_CHART_VERSION}"
Expand All @@ -138,52 +137,61 @@ publishHelmChart() {
CHART_NAME=$1
RELEASE_VERSION=$2
RELEASE_REPO=$3
HELM_CHART_VERSION=$(helmChartVersion $RELEASE_VERSION)
HELM_CHART_VERSION=$(helmChartVersion "$RELEASE_VERSION")
HELM_CHART_FILE_NAME="${CHART_NAME}-${HELM_CHART_VERSION}.tgz"

cd charts
helm dependency update "${CHART_NAME}"
helm lint "${CHART_NAME}"
helm package "${CHART_NAME}" --version $HELM_CHART_VERSION
helm package "${CHART_NAME}" --version "$HELM_CHART_VERSION"
helm push "${HELM_CHART_FILE_NAME}" "oci://${RELEASE_REPO}"
rm "${HELM_CHART_FILE_NAME}"
cd ..
}

createNewWebsiteDirectory() {
RELEASE_VERSION=$1
mkdir -p website/content/en/${RELEASE_VERSION}
cp -r website/content/en/preview/* website/content/en/${RELEASE_VERSION}/
find website/content/en/${RELEASE_VERSION}/ -type f | xargs perl -i -p -e "s/{{< param \"latest_release_version\" >}}/${RELEASE_VERSION}/g;"
find website/content/en/${RELEASE_VERSION}/*/*/*.yaml -type f | xargs perl -i -p -e "s/preview/${RELEASE_VERSION}/g;"
}
versionData "${RELEASE_VERSION}"

editWebsiteConfig() {
RELEASE_VERSION=$1
mkdir -p "website/content/en/${RELEASE_MINOR_VERSION}"
cp -r website/content/en/preview/* "website/content/en/${RELEASE_MINOR_VERSION}/"
find "website/content/en/${RELEASE_MINOR_VERSION}/" -type f | xargs perl -i -p -e "s/{{< param \"latest_release_version\" >}}/${RELEASE_VERSION}/g;"
find website/content/en/${RELEASE_MINOR_VERSION}/*/*/*.yaml -type f | xargs perl -i -p -e "s/preview/${RELEASE_MINOR_VERSION}/g;"
find "website/content/en/${RELEASE_MINOR_VERSION}/" -type f | xargs perl -i -p -e "s/{{< githubRelRef >}}/\/${RELEASE_VERSION}\//g;"

# sed has a different syntax on mac
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' '/^\/docs\/\*/d' website/static/_redirects
else
sed -i '/^\/docs\/\*/d' website/static/_redirects
fi
rm -rf website/content/en/docs
mkdir -p website/content/en/docs
cp -r website/content/en/${RELEASE_MINOR_VERSION}/* website/content/en/docs/
}

echo "/docs/* /${RELEASE_VERSION}/:splat" >>website/static/_redirects
removeOldWebsiteDirectories() {
local n=5
# Get all the directories except the last n directories sorted from earliest to latest version
last_n_versions=$(find website/content/en/* -type d -name "*" -maxdepth 0 | grep -v "preview\|docs" | sort | tail -n "$n")
last_n_versions+=$(echo -e "\nwebsite/content/en/preview")
last_n_versions+=$(echo -e "\nwebsite/content/en/docs")
all=$(find website/content/en/* -type d -name "*" -maxdepth 0)
## symmetric difference
comm -3 <(sort <<< $last_n_versions) <(sort <<< $all) | tr -d '\t' | xargs -r -n 1 rm -r
}

editWebsiteConfig() {
RELEASE_VERSION=$1
yq -i ".params.latest_release_version = \"${RELEASE_VERSION}\"" website/config.yaml
yq -i ".menu.main[] |=select(.name == \"Docs\") .url = \"${RELEASE_VERSION}\"" website/config.yaml
}

# editWebsiteVersionsMenu sets relevant releases in the version dropdown menu of the website
# without increasing the size of the set.
# TODO: We need to maintain a list of latest minors here only. This is not currently
# easy to achieve, however when we have a major release and we decide to maintain
# a selected minor releases we can maintain that list in the repo and use it in here
editWebsiteVersionsMenu() {
RELEASE_VERSION=$1
VERSIONS=(${RELEASE_VERSION})
versionData "${RELEASE_VERSION}"
VERSIONS=("${RELEASE_MINOR_VERSION}")
while IFS= read -r LINE; do
SANITIZED_VERSION=$(echo "${LINE}" | sed -e 's/["-]//g' -e 's/ *//g')
# Bail from this config.yaml update if the version is already in the existing list
if [[ "${RELEASE_MINOR_VERSION}" == "${SANITIZED_VERSION}" ]]; then
return
fi
VERSIONS+=("${SANITIZED_VERSION}")
done < <(yq '.params.versions' website/config.yaml)
unset VERSIONS[${#VERSIONS[@]}-2]
Expand Down
15 changes: 8 additions & 7 deletions hack/release/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
set -euo pipefail

GIT_TAG=$(git describe --exact-match --tags || echo "no tag")
if [[ "$GIT_TAG" == "no tag" ]]; then
echo "Failed to release: commit is untagged"
exit 1
fi
HEAD_HASH=$(git rev-parse HEAD)

SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
source "${SCRIPT_DIR}/common.sh"

config
release $HEAD_HASH #release a snapshot version
## Reset changes if it's a snapshot since we don't need to track these changes
## and results in a -dirty commit hash for a stable release
git reset --hard

if [[ $(releaseType $GIT_TAG) == $RELEASE_TYPE_STABLE ]]; then
release $GIT_TAG
# Don't release with a dirty commit!
if [[ "$(git status --porcelain)" != "" ]]; then
exit 1
fi

release "$GIT_TAG"