release #379
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: Version to release (e.g. v1.2.3) | |
| required: true | |
| kind: | |
| description: Release kind | |
| type: choice | |
| options: [minor, patch] | |
| required: true | |
| default: minor | |
| overwrite_published_release: | |
| description: Tick this box if you want to overwrite a published release and have a good reason for doing so. | |
| type: boolean | |
| required: false | |
| default: false | |
| checkout_main_ref: | |
| description: Checkout this git ref as main branch (some workflows run on this state) | |
| type: string | |
| required: false | |
| default: main | |
| env: | |
| container_registry: ghcr.io/edgelesssys | |
| azure_resource_group: contrast-ci | |
| DO_NOT_TRACK: 1 | |
| concurrency: | |
| group: ${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| process-inputs: | |
| name: Process inputs | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: write | |
| env: | |
| FULL_VERSION: ${{ inputs.version }} | |
| outputs: | |
| WITHOUT_V: ${{ steps.version-info.outputs.WITHOUT_V }} | |
| PART_MAJOR: ${{ steps.version-info.outputs.PART_MAJOR }} | |
| PART_MINOR: ${{ steps.version-info.outputs.PART_MINOR }} | |
| PART_PATCH: ${{ steps.version-info.outputs.PART_PATCH }} | |
| MAJOR: ${{ steps.version-info.outputs.MAJOR }} | |
| MAJOR_MINOR: ${{ steps.version-info.outputs.MAJOR_MINOR }} | |
| MAJOR_MINOR_PATCH: ${{ steps.version-info.outputs.MAJOR_MINOR_PATCH }} | |
| RELEASE_BRANCH: ${{ steps.version-info.outputs.RELEASE_BRANCH }} | |
| WORKING_BRANCH: ${{ steps.version-info.outputs.WORKING_BRANCH }} | |
| NEXT_MINOR: ${{ steps.version-info.outputs.NEXT_MINOR }} | |
| NEXT_MINOR_PRE_WITHOUT_V: ${{ steps.version-info.outputs.NEXT_MINOR_PRE_WITHOUT_V }} | |
| NEXT_PATCH_PRE_WITHOUT_V: ${{ steps.version-info.outputs.NEXT_PATCH_PRE_WITHOUT_V }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Working branch | |
| run: | | |
| echo "WORKING_BRANCH=$(git branch --show-current)" | tee -a "$GITHUB_ENV" | |
| - name: Verify minor version bump | |
| if: inputs.kind == 'minor' | |
| run: | | |
| if [[ ! "${FULL_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "Version must be in the form of vX.Y.Z" | |
| exit 1 | |
| fi | |
| - name: Verify patch version bump | |
| if: inputs.kind == 'patch' | |
| run: | | |
| if [[ ! "${FULL_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[1-9]+$ ]]; then | |
| echo "Version must be in the form of vX.Y.Z, where Z > 0" | |
| exit 1 | |
| fi | |
| - name: Verify temporary branch for minor release | |
| run: | | |
| if [[ ! "${WORKING_BRANCH}" =~ ^tmp/v[0-9]+\.[0-9]+\.[0-9] ]]; then | |
| echo "Workflow can only be triggered from a temporary branch in the form of tmp/vX.Y.Z" | |
| exit 1 | |
| fi | |
| - name: Extract version info | |
| id: version-info | |
| run: | | |
| WITHOUT_V=${FULL_VERSION#v} | |
| PART_MAJOR=${WITHOUT_V%%.*} | |
| PART_MINOR=${WITHOUT_V#*.} | |
| PART_MINOR=${PART_MINOR%%.*} | |
| PART_PATCH=${WITHOUT_V##*.} | |
| RELEASE_BRANCH=release/v${PART_MAJOR}.${PART_MINOR} | |
| NEXT_MINOR=${PART_MAJOR}.$((PART_MINOR + 1)).0 | |
| NEXT_MINOR_PRE_WITHOUT_V=${PART_MAJOR}.$((PART_MINOR + 1)).0-pre | |
| NEXT_PATCH_PRE_WITHOUT_V=${PART_MAJOR}.${PART_MINOR}.$((PART_PATCH + 1))-pre | |
| { | |
| echo "WITHOUT_V=${WITHOUT_V}" | |
| echo "PART_MAJOR=${PART_MAJOR}" | |
| echo "PART_MINOR=${PART_MINOR}" | |
| echo "PART_PATCH=${PART_PATCH}" | |
| echo "MAJOR=${PART_MAJOR}" | |
| echo "MAJOR_MINOR=${PART_MAJOR}.${PART_MINOR}" | |
| echo "MAJOR_MINOR_PATCH=${PART_MAJOR}.${PART_MINOR}.${PART_PATCH}" | |
| echo "RELEASE_BRANCH=${RELEASE_BRANCH}" | |
| echo "WORKING_BRANCH=${WORKING_BRANCH}" | |
| echo "NEXT_MINOR=${NEXT_MINOR}" | |
| echo "NEXT_MINOR_PRE_WITHOUT_V=${NEXT_MINOR_PRE_WITHOUT_V}" | |
| echo "NEXT_PATCH_PRE_WITHOUT_V=${NEXT_PATCH_PRE_WITHOUT_V}" | |
| } | tee -a "$GITHUB_OUTPUT" | |
| echo "RELEASE_BRANCH=${RELEASE_BRANCH}" | tee -a "$GITHUB_ENV" | |
| - name: Don't overwrite published releases | |
| if: (! inputs.overwrite_published_release) | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| is_draft=$(gh release view "${FULL_VERSION}" --json isDraft -q .isDraft || true) | |
| # If the release is not yet published, is_draft will either be "true" or empty. | |
| if [[ "${is_draft}" == "false" ]]; then | |
| echo "::error::Release ${FULL_VERSION} is already published." | |
| exit 1 | |
| fi | |
| update-main: | |
| name: Update main branch | |
| runs-on: ubuntu-24.04 | |
| needs: [process-inputs, release] | |
| permissions: | |
| contents: write | |
| env: | |
| RELEASE_BRANCH: ${{ needs.process-inputs.outputs.RELEASE_BRANCH }} | |
| WORKING_BRANCH: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| VERSION: ${{ inputs.version }} | |
| MAJOR_MINOR: ${{ needs.process-inputs.outputs.MAJOR_MINOR }} | |
| MAJOR_MINOR_PATCH: ${{ needs.process-inputs.outputs.MAJOR_MINOR_PATCH }} | |
| SET: base | |
| steps: | |
| - name: Checkout working branch | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| path: contrast-working | |
| persist-credentials: false | |
| - name: Checkout main | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ inputs.checkout_main_ref }} | |
| path: contrast-main | |
| persist-credentials: false | |
| - uses: ./contrast-working/.github/actions/setup_nix | |
| with: | |
| githubToken: ${{ secrets.GITHUB_TOKEN }} | |
| cachixToken: ${{ secrets.CACHIX_AUTH_TOKEN }} | |
| - name: Configure git | |
| run: | | |
| git config --global user.name "edgelessci" | |
| git config --global user.email "edgelessci@users.noreply.github.com" | |
| - name: Create docs release | |
| if: inputs.kind == 'minor' | |
| working-directory: contrast-main/docs | |
| run: | | |
| nix run ".#${SET}.nixpkgs.yarn install" | |
| nix run ".#${SET}.nixpkgs.yarn" docusaurus docs:version "${MAJOR_MINOR}" | |
| git add . | |
| git commit -am "docs: release ${MAJOR_MINOR}" | |
| # Clean up auxiliary files, so next steps run on a clean tree | |
| git clean -fx :/ | |
| git reset --hard HEAD | |
| - name: Download image replacements file (from release branch) | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 | |
| with: | |
| name: image-replacements | |
| - name: Update release urls in docs with tags | |
| working-directory: contrast-main | |
| run: nix run ".#${SET}.scripts.update-release-urls" | |
| - name: Commit updated docs | |
| working-directory: contrast-main | |
| run: | | |
| git add "docs/versioned_docs/version-${MAJOR_MINOR}" | |
| git commit -m "docs: update release download urls" | |
| git clean -fx :/ | |
| git reset --hard HEAD | |
| - name: Download release artifacts (from release branch) | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 | |
| with: | |
| name: contrast-release-artifacts | |
| path: ./contrast-main | |
| - name: Update contrast-releases.json with new release | |
| working-directory: contrast-main | |
| run: nix run ".#${SET}.scripts.update-contrast-releases" | |
| - name: Commit updated contrast-releases.json | |
| working-directory: contrast-main | |
| run: | | |
| git add ./packages/contrast-releases.json | |
| git commit -m "packages/contrast-releases: add ${MAJOR_MINOR_PATCH}" | |
| git clean -fx :/ | |
| git reset --hard HEAD | |
| - name: Bump flake version to post release patch pre-version | |
| if: inputs.kind == 'minor' | |
| id: bump | |
| uses: ./contrast-working/.github/actions/bump_version # Run action from working branch! | |
| with: | |
| version: ${{ needs.process-inputs.outputs.NEXT_MINOR_PRE_WITHOUT_V }} | |
| working-directory: contrast-main | |
| commit: false | |
| - name: Create PR | |
| uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 | |
| with: | |
| title: Post ${{ needs.process-inputs.outputs.WITHOUT_V }} release updates to main | |
| body: | | |
| Updating main as part of the ${{ needs.process-inputs.outputs.WITHOUT_V }} release. | |
| Only merge after the release is published. | |
| commit-message: ${{ steps.bump.outputs.commit-msg }} | |
| base: main | |
| draft: false | |
| labels: "no changelog" | |
| branch: automated/update-main-after-${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| committer: edgelessci <edgelessci@users.noreply.github.com> | |
| author: edgelessci <edgelessci@users.noreply.github.com> | |
| token: ${{ secrets.NUNKI_CI_COMMIT_PUSH_PR }} | |
| path: ./contrast-main | |
| release: | |
| name: Build and push artifacts, create release | |
| runs-on: ubuntu-24.04 | |
| needs: process-inputs | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write | |
| env: | |
| RELEASE_BRANCH: ${{ needs.process-inputs.outputs.RELEASE_BRANCH }} | |
| WORKING_BRANCH: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| VERSION: ${{ inputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| persist-credentials: true | |
| - uses: ./.github/actions/setup_nix | |
| with: | |
| githubToken: ${{ secrets.GITHUB_TOKEN }} | |
| cachixToken: ${{ secrets.CACHIX_AUTH_TOKEN }} | |
| - name: Log in to ghcr.io Container registry | |
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure git | |
| run: | | |
| git config --global user.name "edgelessci" | |
| git config --global user.email "edgelessci@users.noreply.github.com" | |
| - name: Bump flake version to release version | |
| uses: ./.github/actions/bump_version | |
| with: | |
| version: ${{ needs.process-inputs.outputs.WITHOUT_V }} | |
| commit: true | |
| - name: Create release artifacts | |
| id: create-artifacts | |
| uses: ./.github/actions/release_artifacts | |
| with: | |
| version: ${{ inputs.version }} | |
| container_registry: ${{ env.container_registry }} | |
| s3-bucket-path: "pre-releases/${{ inputs.version }}" | |
| - name: Upload release artifacts (for main branch PR) | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: contrast-release-artifacts | |
| # Keep the LICENSE file! It isn't used, but ensures the paths of the other artifacts aren't stripped, see | |
| # https://github.com/actions/upload-artifact/blob/6027e3dd177782cd8ab9af838c04fd81a07f1d47/README.md?plain=1#L187 | |
| path: | | |
| LICENSE | |
| ${{ steps.create-artifacts.outputs.paths }} | |
| - name: Create draft release | |
| uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 | |
| with: | |
| draft: true | |
| generate_release_notes: true | |
| tag_name: ${{ inputs.version }} | |
| target_commitish: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| fail_on_unmatched_files: true | |
| files: ${{ steps.create-artifacts.outputs.paths }} | |
| - name: Reset temporary changes | |
| run: | | |
| git reset --hard "${WORKING_BRANCH}" | |
| - name: Bump flake version to post release patch pre-version | |
| uses: ./.github/actions/bump_version | |
| with: | |
| version: ${{ needs.process-inputs.outputs.NEXT_PATCH_PRE_WITHOUT_V }} | |
| commit: true | |
| test: | |
| strategy: | |
| matrix: | |
| platform: | |
| - name: Metal-QEMU-SNP | |
| node-installer-target-conf: none | |
| runner: SNP | |
| self-hosted: true | |
| - name: Metal-QEMU-SNP-GPU | |
| node-installer-target-conf: k3s | |
| runner: SNP-GPU | |
| self-hosted: true | |
| - name: Metal-QEMU-TDX | |
| node-installer-target-conf: k3s | |
| runner: TDX | |
| self-hosted: true | |
| - name: Metal-QEMU-TDX-GPU | |
| node-installer-target-conf: k3s | |
| runner: TDX-GPU | |
| self-hosted: true | |
| fail-fast: false | |
| name: "e2e release on ${{ matrix.platform.name }}" | |
| runs-on: ${{ matrix.platform.runner }} | |
| permissions: | |
| # Job needs content:write to see draft releases. | |
| contents: write | |
| packages: read | |
| needs: [process-inputs, release, nightly] | |
| env: | |
| VERSION: ${{ inputs.version }} | |
| SET: base | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| persist-credentials: false | |
| - uses: ./.github/actions/setup_nix | |
| if: (!matrix.platform.self-hosted) | |
| with: | |
| githubToken: ${{ secrets.GITHUB_TOKEN }} | |
| cachixToken: ${{ secrets.CACHIX_AUTH_TOKEN }} | |
| - uses: nicknovitski/nix-develop@9be7cfb4b10451d3390a75dc18ad0465bed4932a # v1.2.1 | |
| - name: Log in to ghcr.io Container registry | |
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create justfile.env | |
| run: | | |
| cat <<EOF > justfile.env | |
| container_registry=${{ env.container_registry }} | |
| azure_resource_group=${{ env.azure_resource_group }} | |
| default_platform=${{ matrix.platform.name }} | |
| EOF | |
| - name: Get credentials for CI cluster | |
| if: (!matrix.platform.self-hosted) | |
| run: | | |
| just get-credentials | |
| - name: Request fifo ticket | |
| if: (!matrix.platform.self-hosted || matrix.platform.name == 'Metal-QEMU-SNP-GPU' || matrix.platform.name == 'Metal-QEMU-TDX-GPU') | |
| run: | | |
| just request-fifo-ticket | |
| - name: E2E Test | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| mkdir -p workspace | |
| nix build ".#${SET}.scripts.get-logs" | |
| nix run ".#${SET}.scripts.get-logs start" workspace/just.namespace & | |
| nix shell -L ".#${SET}.contrast.e2e" --command release.test \ | |
| -test.v \ | |
| --tag "${VERSION}" \ | |
| --platform ${{ matrix.platform.name }} \ | |
| --node-installer-target-conf ${{ matrix.platform.node-installer-target-conf }} \ | |
| --namespace-file workspace/just.namespace | |
| - name: Download logs | |
| if: always() | |
| run: | | |
| nix run ".#${SET}.scripts.get-logs download" workspace/just.namespace | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| kubectl delete -f workspace/log-collector.yaml | |
| rm -f workspace/just.namespace | |
| - name: Upload logs | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: e2e_pod_logs-${{ matrix.platform.name }}-release | |
| path: workspace/logs | |
| if-no-files-found: error | |
| - name: Release fifo ticket | |
| if: always() && (!matrix.platform.self-hosted || matrix.platform.name == 'Metal-QEMU-SNP-GPU' || matrix.platform.name == 'Metal-QEMU-TDX-GPU') | |
| run: | | |
| just release-fifo-ticket | |
| nightly: | |
| name: e2e nightly | |
| needs: release | |
| uses: ./.github/workflows/e2e_nightly.yml | |
| secrets: | |
| GITHUB_TOKEN_IN: ${{ secrets.GITHUB_TOKEN }} | |
| CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} | |
| NUNKI_CI_COMMIT_PUSH_PR: ${{ secrets.NUNKI_CI_COMMIT_PUSH_PR }} | |
| TEAMS_CI_WEBHOOK: ${{ secrets.TEAMS_CI_WEBHOOK }} | |
| CONTRAST_GHCR_READ: ${{ secrets.CONTRAST_GHCR_READ }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| publish: | |
| name: Publish release | |
| needs: [process-inputs, release, test] | |
| runs-on: ubuntu-24.04 | |
| environment: release-publish | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Publish release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| VERSION: ${{ inputs.version }} | |
| run: | | |
| gh release edit "${VERSION}" --draft=false --repo "${{ github.repository }}" | |
| create-github-stuff: | |
| name: Create backport label and milestone | |
| if: inputs.kind == 'minor' | |
| needs: process-inputs | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| issues: write | |
| contents: read | |
| env: | |
| RELEASE_BRANCH: ${{ needs.process-inputs.outputs.RELEASE_BRANCH }} | |
| NEXT_MINOR: ${{ needs.process-inputs.outputs.NEXT_MINOR }} | |
| GH_TOKEN: ${{ github.token }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} | |
| persist-credentials: false | |
| - name: Create backport label | |
| run: | | |
| gh label create "backport ${RELEASE_BRANCH}" --color 576F61 --force | |
| - name: Create milestone | |
| run: | | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| /repos/edgelesssys/contrast/milestones | | |
| jq -r '.[] | .title' | \ | |
| grep -xqF "v${NEXT_MINOR}" && exit 0 | |
| gh api \ | |
| --method POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| /repos/edgelesssys/contrast/milestones \ | |
| -f title="v${NEXT_MINOR}" \ | |
| -f state='open' |