name: Release

on:
  push:
    tags:
      - "edge-*"

permissions:
  contents: read

env:
  GH_ANNOTATION: true
  DOCKER_REGISTRY: ghcr.io/linkerd
  K3D_VERSION: v5.8.3
  LINKERD2_PROXY_REPO: ${{ vars.LINKERD2_PROXY_REPO }}

jobs:
  # TODO(ver) We should stop relying so heavily on the environment,
  # especially the TAG variable. And it would be great to stop relying
  # on the root-tag script altogether.
  tag:
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      - run: echo "tag=$(CI_FORCE_CLEAN=1 bin/root-tag)" >> "$GITHUB_OUTPUT"
        id: tag
      - name: Validate edge version
        run: bin/compute-edge-version
    outputs:
      tag: ${{ steps.tag.outputs.tag }}

  docker_build:
    name: Docker build
    needs: [tag]
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    permissions:
      contents: read
      packages: write # for docker/login-action
      id-token: write # for cosign
    strategy:
      matrix:
        component:
          - cli-bin
          - controller
          - debug
          - jaeger-webhook
          - metrics-api
          - proxy
          - tap
          - web
    timeout-minutes: 45
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      - name: Set tag
        run: echo 'TAG=${{ needs.tag.outputs.tag }}' >> "$GITHUB_ENV"
      - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
        with:
          registry: ghcr.io
          username: ${{ secrets.DOCKER_GHCR_USERNAME }}
          password: ${{ secrets.DOCKER_GHCR_PAT }}
      - uses: ./.github/actions/docker-build
        id: build
        with:
          docker-registry: ${{ env.DOCKER_REGISTRY }}
          docker-target: multi-arch
          docker-push: 1
          component: ${{ matrix.component }}
          tag: ${{ needs.tag.outputs.tag }}
        env:
          LINKERD2_PROXY_GITHUB_TOKEN: ${{ secrets.LINKERD2_PROXY_GITHUB_TOKEN }}
      - uses: sigstore/cosign-installer@v3
      - run: cosign sign '${{ steps.build.outputs.digest }}'
        env:
          COSIGN_YES: true
      - name: Create artifact with CLI
        # windows_static_cli_tests below needs this because it can't create linux containers
        # inside windows
        if: matrix.component == 'cli-bin'
        env:
          ARCHIVES: /home/runner/archives
          DOCKER_TARGET: windows
        run: |
          bin/docker-pull-binaries "$TAG"
          mkdir -p "$ARCHIVES"
          cp -r "$PWD/target/release/linkerd2-cli-$TAG-windows.exe" "$ARCHIVES/linkerd-windows.exe"
      # `with.path` values do not support environment variables yet, so an
      # absolute path is used here.
      # https://github.com/actions/upload-artifact/issues/8
      - name: Upload artifact
        if: matrix.component == 'cli-bin'
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
        with:
          name: image-archives-cli
          path: /home/runner/archives

  windows_static_cli_tests:
    name: Static CLI tests (windows)
    timeout-minutes: 30
    runs-on: windows-latest
    needs: [docker_build]
    steps:
      - name: Checkout code
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
        with:
          go-version: "1.24"
      - name: Download image archives
        uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
        with:
          name: image-archives-cli
          path: image-archives
      - name: Run CLI Integration tests
        run: go test --failfast --mod=readonly ".\test\cli" --linkerd="$PWD\image-archives\linkerd-windows.exe" --cli-tests -v

  integration_tests:
    name: Integration tests
    needs: [tag, docker_build]
    strategy:
      matrix:
        integration_test:
          - cluster-domain
          - cni-calico-deep
          - deep
          - viz
          - default-policy-deny
          - external
          - rsa-ca
          - helm-upgrade
          - uninstall
          - upgrade-edge
    timeout-minutes: 60
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    steps:
      - name: Checkout code
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
        with:
          go-version: "1.24"
      - name: Set environment variables from scripts
        run: |
          TAG='${{ needs.tag.outputs.tag }}'
          CMD="$PWD/target/release/linkerd2-cli-$TAG-linux-amd64"
          echo "CMD=$CMD" >> "$GITHUB_ENV"
          echo "TAG=$TAG" >> "$GITHUB_ENV"
      - name: Run integration tests
        env:
          LINKERD_DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
        run: |
          bin/docker-pull-binaries "$TAG"
          # Validate the CLI version matches the current build tag.
          [[ "$TAG" == "$($CMD version --short --client)" ]]
          bin/tests --images preload --name ${{ matrix.integration_test }} "$CMD"

  gh_release:
    name: Create GH release
    needs:
      - tag
      - integration_tests
    timeout-minutes: 30
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      # - name: Download choco package
      #   if: startsWith(github.ref, 'refs/tags/stable')
      #   uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
      #   with:
      #     name: choco
      #     path: choco
      - name: Pull CLI binaries
        run: DOCKER_TARGET=multi-arch bin/docker-pull-binaries '${{ needs.tag.outputs.tag }}'
        #  v=${TAG#"stable-"}
        #  mv choco/linkerd.*.nupkg "target/release/linkerd2-cli-stable-$v.nupkg" || true
      - name: Create release
        id: create_release
        uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8
        with:
          name: "${{ needs.tag.outputs.tag }}"
          generate_release_notes: true
          draft: false
          prerelease: false
          files: |
            ./target/release/linkerd2-cli-*-darwin*
            ./target/release/linkerd2-cli-*-linux-*
            ./target/release/linkerd2-cli-*-windows.*
            ./target/release/linkerd2-cli-*.nupkg

  website_publish:
    name: Linkerd website publish
    needs: [chart_deploy]
    if: startsWith(github.ref, 'refs/tags/stable') || startsWith(github.ref, 'refs/tags/edge')
    timeout-minutes: 30
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    permissions:
      contents: write
    steps:
      - name: Create linkerd/website repository dispatch event
        uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0
        with:
          token: ${{ secrets.RELEASE_TOKEN }}
          repository: linkerd/website
          event-type: release

  website_publish_check:
    name: Linkerd website publish check
    needs: [tag, website_publish]
    timeout-minutes: 30
    if: startsWith(github.ref, 'refs/tags/stable') || startsWith(github.ref, 'refs/tags/edge')
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      - name: Set install target for stable
        if: startsWith(github.ref, 'refs/tags/stable')
        run: echo "INSTALL=install" >> "$GITHUB_ENV"
      - name: Set install target for edge
        if: startsWith(github.ref, 'refs/tags/edge')
        run: echo "INSTALL=install-edge" >> "$GITHUB_ENV"
      - name: Check published version
        shell: bash
        run: |
          TAG='${{ needs.tag.outputs.tag }}'
          until RES=$(bin/scurl "https://run.linkerd.io/$INSTALL" | grep "LINKERD2_VERSION=\${LINKERD2_VERSION:-$TAG}") \
            || (( count++ >= 10 ))
          do
            sleep 30
          done
          if [[ -z "$RES" ]]; then
            echo "::error::The version '$TAG' was NOT found published in the website"
            exit 1
          fi

  chart_deploy:
    name: Helm chart deploy
    needs: [gh_release]
    timeout-minutes: 30
    runs-on: ${{ vars.LINKERD2_RUNNER || 'ubuntu-24.04' }}
    steps:
      - name: Checkout code
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
      - name: Log into GCP
        uses: "google-github-actions/auth@b7593ed2efd1c1617e1b0254da33b86225adb2a5"
        with:
          credentials_json: ${{ secrets.LINKERD_SITE_TOKEN }}
      - name: Edge Helm chart creation and upload
        uses: ./.github/actions/helm-publish
