diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..41d331a1b9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,89 @@ +# Run on tag push. +# Note: Additionally, create the release branch. +on: + push: + tags: + - v* + +permissions: + contents: read + +env: + GO_VERSION_MATRIX: '"go-version":["^1.21","latest"]' + GOLANGCI_LINT_VERSION: "v1.54.2" + E2E_SETUP_KIND: yes + E2E_SETUP_KUBECTL: yes + +jobs: + setup: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - id: set-matrix + run: echo ::set-output name=matrix::{${{ env.GO_VERSION_MATRIX }}} + release: + needs: setup + strategy: + matrix: ${{fromJson(needs.setup.outputs.matrix)}} + runs-on: ubuntu-latest + steps: + - name: Checkout into the repository in a new branch + uses: actions/checkout@v4 + with: + ref: release-${{ github.ref }} + repository: ${{ github.event.repository.full_name }} + - name: Set up the Go@${{ matrix.go-version }} environment + uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go-version }} + - name: Install tools + run: make install-tools + - name: Get the pushed tag + id: get_tag + run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} + - name: Update the VERSION manifest to the pushed tag + run: echo "${{ steps.get_tag.outputs.tag }}" > VERSION + - name: Update the compatibility matrix (README.md) + run: ./scripts/update-compatibility-matrix.sh + - name: Generate the release notes (CHANGELOG.md) + run: ./scripts/generate-release-notes.sh + - name: Lint + run: | + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \ + sh -s -- -b $(go env GOPATH)/bin ${{ env.GOLANGCI_LINT_VERSION }} + make lint-fix + - name: Generate manifests + run: make examples + - name: Validate manifests + run: make validate-manifests + - name: Validate docs + run: make validate-docs + - name: Validate go modules + run: make validate-modules + - name: Run rule tests + run: PROMTOOL_CLI=./promtool make install-promtool test-rules + - name: Run unit tests + run: make test-unit + - name: Benchmark tests + run: make test-benchmark-compare + - name: Run end-to-end tests + run: make e2e + - name: Commit the changes + run: | + git config --local user.email "release-bot@ksm.k8s.io" + git config --local user.name "KSM Release Bot" + git add . + git commit -m "chore: Cut ${{ steps.get_tag.outputs.tag }}" + - name: Create a pull request + uses: peter-evans/create-pull-request@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: Cut ${{ steps.get_tag.outputs.tag }}" + title: "chore: Cut ${{ steps.get_tag.outputs.tag }}" + body: "This PR was automatically created by the release workflow." + branch: release-${{ steps.get_tag.outputs.tag }} + base: release-${{ steps.get_tag.outputs.tag }} + reviewers: "sig-instrumentation-approvers" + assignees: "sig-instrumentation-leads" + draft: false diff --git a/scripts/generate-release-notes.sh b/scripts/generate-release-notes.sh new file mode 100644 index 0000000000..85e5c00ffc --- /dev/null +++ b/scripts/generate-release-notes.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Fetch the latest two tags. +# NOTE: This assumes a patch release for an older release is not made after a later minor release (which is the case right now). +# Backports will be handled manually, on a case-by-case basis. +last_two_tags=$(git tag --sort=-creatordate | head -n 2) +IFS=$'\n' read -d '' -r -a tags <<< "$last_two_tags" +commits=$(git log --pretty=format:"%h: %an <%ae>: %s" "${tags[1]}".."${tags[0]}" | grep -i -v -e 'fixup' -e 'merge' -e 'dependabot') + +# Update the changelog with the latest release notes. +echo -e "## ${tags[0]}\n\n$commits\n$(cat CHANGELOG.md)" > CHANGELOG.md diff --git a/scripts/update-compatibility-matrix.sh b/scripts/update-compatibility-matrix.sh new file mode 100644 index 0000000000..b7b65c9b21 --- /dev/null +++ b/scripts/update-compatibility-matrix.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Fetch the latest tag +latest_tag=$(git describe --tags "$(git rev-list --tags --max-count=1)") + +# Determine if it's a patch release or not (minor and major releases are handled the same way in the compat-matrix). +if [[ $latest_tag =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + IFS='.' read -ra TAG <<< "$latest_tag" + if [[ ${#TAG[@]} -eq 2 ]]; then + # Prep for a non-patch release. + client_go_version=$(awk '/\| \*\*main\*\*/ {print $4}' README.md) + sed -i "/| \*\*main\*\* | $client_go_version |/i| \*\*$latest_tag\*\* | $client_go_version |\n| \*\*main\*\* | $client_go_version |" README.md + oldest_supported_client_go_version=$(awk 'NR==2 {print $4; exit}' README.md) + # Remove the first row + sed -i "/| \*\*.*\*\* | $oldest_supported_client_go_version |/d" README.md + elif [[ ${#TAG[@]} -eq 3 ]]; then + # Prep for a patch release. + minor_release="${TAG[0]}.${TAG[1]}" + # Get the client-go version of the minor release row + client_go_version=$(awk -v release="| \*\*$minor_release.*\*\*" '$0 ~ release {print $4}' README.md) + # Update the row with the latest tag and client-go version + sed -i "s/| \*\*$minor_release.*\*\* | $client_go_version |/| \*\*$latest_tag\*\* | $client_go_version |/" README.md + else + echo "Bad tag format: $latest_tag, expected one of the following formats: \ + * vMAJOR.MINOR (non-patch release) \ + * vMAJOR.MINOR.PATCH (patch release)" + exit 1 + fi +else + echo "Bad tag format: $latest_tag, expected one of the following formats: \ + * vMAJOR.MINOR (non-patch release) \ + * vMAJOR.MINOR.PATCH (patch release)" + exit 1 +fi