name: K3s Release

on:
  push:
    tags:
    - "v*"

permissions:
  contents: read
  packages: read
  id-token: write

jobs:
  build-amd64:
    name: Build Binary (amd64)
    uses: ./.github/workflows/build-k3s.yaml
    with:
      platforms: linux/amd64
      upload-build: true

  build-arm:
    name: Build Binary (arm64)
    uses: ./.github/workflows/build-k3s.yaml
    with:
      platforms: linux/arm64,linux/arm/v7
      upload-build: true

  push-release-image:
    name: Build and Push Multi-Arch Image
    runs-on: ubuntu-latest
    permissions: 
      packages: write # Needed to push images to GHCR
      id-token: write
    needs: [build-amd64, build-arm]
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Set up Docker
        uses: docker/setup-docker-action@0234bb73ccb40f0c430b795634f9247e2b5c2d23 # v5
        with:
          version: type=image,tag=29
          daemon-config: '{"features":{"containerd-snapshotter":true}}'
          set-host: true

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

      - name: Read registry secrets (staging)
        uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
        if: ${{ github.repository_owner == 'k3s-io' }}
        with:
          secrets: |
            secret/data/github/repo/${{ github.repository }}/k3s-suse-registry-stg/credentials registry | STAGING_REGISTRY ;
            secret/data/github/repo/${{ github.repository }}/k3s-suse-registry-stg/credentials username | STAGING_REGISTRY_USERNAME ;
            secret/data/github/repo/${{ github.repository }}/k3s-suse-registry-stg/credentials password | STAGING_REGISTRY_PASSWORD

      - name: Read registry secrets (prime)
        uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
        if: ${{ !contains(github.ref_name, '-rc') && github.repository_owner == 'k3s-io' }}
        with:
          secrets: |
            secret/data/github/repo/${{ github.repository }}/k3s-suse-registry/credentials registry | REGISTRY ;
            secret/data/github/repo/${{ github.repository }}/k3s-suse-registry/credentials username | REGISTRY_USERNAME ;
            secret/data/github/repo/${{ github.repository }}/k3s-suse-registry/credentials password | REGISTRY_PASSWORD

      - name: "Read Vault secrets"
        if: github.repository_owner == 'k3s-io'
        uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
        with:
          secrets: |
            secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ;
            secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_TOKEN ;
    
      - name: Login to DockerHub with Rancher Secrets
        if: github.repository_owner == 'k3s-io'
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
        with:
          username: ${{ env.DOCKER_USERNAME }}
          password: ${{ env.DOCKER_TOKEN }}

      # For forks, setup DockerHub login with GHA secrets
      - name: Login to DockerHub with GHA Secrets
        if: github.repository_owner != 'k3s-io'
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Login to Staging Registry
        if: github.repository_owner == 'k3s-io'
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
        with:
          registry: ${{ env.STAGING_REGISTRY }}
          username: ${{ env.STAGING_REGISTRY_USERNAME }}
          password: ${{ env.STAGING_REGISTRY_PASSWORD }}

      - name: Login to Prime Registry
        if: ${{ !contains(github.ref_name, '-rc') && github.repository_owner == 'k3s-io' }}
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ env.REGISTRY_USERNAME }}
          password: ${{ env.REGISTRY_PASSWORD }}

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Configure image tags
        id: tag_config
        run: |
          TAG=${GITHUB_REF#refs/tags/}
          
          # Base configuration - always transform the main tag
          # Transforms v1.32.4-rc1+k3s1 → v1.32.4-rc1-k3s1
          BASE_CONFIG="type=raw,value=${TAG//+/-}"
          
          if [[ "${TAG,,}" == *"rc"* ]]; then
            echo "RC release detected: $TAG"
            echo "tag_spec=$BASE_CONFIG" >> $GITHUB_OUTPUT
          else
            echo "Stable release detected: $TAG"
            echo "tag_spec=$BASE_CONFIG
          type=semver,pattern=v{{major}}.{{minor}}" >> $GITHUB_OUTPUT
          fi

      - name: Set DockerHub Org
        run: |
          if [ "${{ github.repository_owner }}" == "k3s-io" ]; then
            echo "DOCKERHUB_ORG=rancher" >> $GITHUB_ENV
          else
            echo "DOCKERHUB_ORG=${{ secrets.DOCKER_USERNAME }}" >> $GITHUB_ENV
          fi

      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
        with:
          images: |
            ghcr.io/${{ github.repository_owner }}/k3s
            docker.io/${{ env.DOCKERHUB_ORG }}/k3s
            name=${{ env.REGISTRY }}/rancher/k3s,enable=${{ !contains(github.ref_name, '-rc') && github.repository_owner == 'k3s-io' }}
            name=${{ env.STAGING_REGISTRY }}/rancher/k3s,enable=${{ github.repository_owner == 'k3s-io' }}
          flavor: latest=false
          tags: ${{ steps.tag_config.outputs.tag_spec }}
      
      - name: "Download K3s build"
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
        with:
          pattern: k3s*
          path: ./dist/artifacts
          merge-multiple: true

      - name: Prepare build folder
        run: |
          mkdir -p ./build/out
          cp ./dist/artifacts/data-* ./build/out

      - name: Build and push K3s runtime image
        uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
        with:
          context: .
          file: ./package/Dockerfile
          platforms: linux/amd64,linux/arm64,linux/arm/v7
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          build-args: |
            TAG=${{ github.ref_name }}

  build-airgap:
    name: Airgap Image Tarballs
    uses: ./.github/workflows/airgap.yaml

  upload-release-assets:
    name: Prepare and Upload Release Assets
    permissions: 
      contents: write # Needed to update release with assets
      id-token: write
    runs-on: ubuntu-latest
    needs: [build-amd64, build-arm, build-airgap]
    steps:
    - name: Checkout code
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

    - name: Read Prime artifacts secrets
      uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
      if: ${{ github.repository_owner == 'k3s-io' }}
      with:
        secrets: |
          secret/data/github/repo/${{ github.repository }}/prime-artifacts-uploader/credentials accessKeyId | AWS_ACCESS_KEY_ID ;
          secret/data/github/repo/${{ github.repository }}/prime-artifacts-uploader/credentials secretAccessKey | AWS_SECRET_ACCESS_KEY ;
          secret/data/github/repo/${{ github.repository }}/prime-artifacts-uploader/credentials primeArtifactsBucketName | PRIME_ARTIFACTS_BUCKET_NAME

    - name: Read registry secrets (staging)
      uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
      if: ${{ contains(github.ref_name, '-rc') && github.repository_owner == 'k3s-io' }}
      with:
        secrets: |
          secret/data/github/repo/${{ github.repository }}/k3s-suse-registry-stg/credentials registry | REGISTRY

    - name: Read registry secrets (prime)
      uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
      if: ${{ !contains(github.ref_name, '-rc') && github.repository_owner == 'k3s-io' }}
      with:
        secrets: |
          secret/data/github/repo/${{ github.repository }}/k3s-suse-registry/credentials registry | REGISTRY

    - name: Configure AWS Credentials (s3)
      uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6
      if: ${{ github.repository_owner == 'k3s-io' }}
      with:
        aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1

    - name: "Download Artifacts"
      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
      with:
        pattern: "*"
        path: ./dist/artifacts
        merge-multiple: true
    
    - name: "Combine and format sha256sum files"
      run: |
        cp scripts/airgap/image-list.txt dist/artifacts/k3s-images.txt
        for ARCH in amd64 arm64 arm; do
          OUTPUT_FILE="./dist/artifacts/sha256sum-${ARCH}.txt"
          cat ./dist/artifacts/k3s-airgap-images-${ARCH}*.sha256sum >> "${OUTPUT_FILE}"
          rm ./dist/artifacts/k3s-airgap-images-${ARCH}*.sha256sum # Remove the original file to avoid uploading it
          if [[ "${ARCH}" == "amd64" ]]; then
            cat ./dist/artifacts/k3s.sha256sum >> "${OUTPUT_FILE}"
            rm ./dist/artifacts/k3s.sha256sum # Remove the original file to avoid uploading it
          else
            cat ./dist/artifacts/k3s-${ARCH}.sha256sum >> "${OUTPUT_FILE}"
            rm ./dist/artifacts/k3s-${ARCH}.sha256sum # Remove the original file to avoid uploading it
          fi
        done

    - name: Validate Assets for Release
      run: |
        ./scripts/validate-artifacts

    - name: Create Pre-Release with Assets
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: gh release create -R "${GITHUB_REPOSITORY}" --prerelease --generate-notes "${GITHUB_REF_NAME}" "${GITHUB_WORKSPACE}"/dist/artifacts/k3s* "${GITHUB_WORKSPACE}"/dist/artifacts/sha256sum*

    - name: Update Image Registry for Prime/Staging
      if: ${{ github.repository_owner == 'k3s-io' }}
      env:
        REGISTRY: ${{ env.REGISTRY }}
      run: sed -i "s|docker.io|${REGISTRY}|g" dist/artifacts/k3s-images.txt

    - name: Upload Assets to S3
      if: ${{ github.repository_owner == 'k3s-io' }}
      env:
        BUCKET: ${{ env.PRIME_ARTIFACTS_BUCKET_NAME }}
      run: |
        S3_PATH="s3://${BUCKET}/k3s/${GITHUB_REF_NAME}"
        aws s3 sync dist/artifacts/ "$S3_PATH" --quiet --no-progress --exclude "*" --include "k3s*" --include "sha256sum*"

  dispatch-k3s-upgrade:
    name: Dispatch k3s-upgrade Workflow
    runs-on: ubuntu-latest
    needs: [upload-release-assets]
    steps:
      - name: Dispatch k3s-upgrade Workflow
        run: |
          curl -L -XPOST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer ${{ secrets.K3S_UPGRADE_PAT }}" \
            -H "Content-Type: application/json" \
            https://api.github.com/repos/${{ github.repository_owner }}/k3s-upgrade/dispatches \
            -d '{"event_type":"tag-release","client_payload":{"tag":"${{ github.ref_name }}"}}'

