name: Release binaries
description: |
  Build, sign, and publish release binaries for a Vikunja sub-project.

  Derives every per-project path, cache key, artifact name, and S3 target
  from the `project` input. Callers only need to provide the project name,
  the raw `git describe` value, and pass through the GPG/S3 secrets as
  inputs (composite actions can't read the `secrets` context directly).

inputs:
  project:
    description: 'Which project to build: "vikunja" or "veans".'
    required: true
  release-version:
    description: |
      Raw git describe value (e.g. v1.2.3 or v2.3.0-408-ge053d317). Always
      passed through to the build so the binary embeds the precise commit.
      Filenames and the S3 directory use "unstable" instead whenever
      github.ref_type isn't "tag".
    required: true
  # Secrets — composite actions can't read the `secrets` context directly, so
  # the caller threads them through as inputs.
  gpg-passphrase:
    required: true
  gpg-sign-key:
    required: true
  s3-access-key-id:
    required: true
  s3-secret-access-key:
    required: true
  s3-endpoint:
    required: true
  s3-bucket:
    required: true
  s3-region:
    required: true

runs:
  using: composite
  steps:
    - name: Set project paths
      shell: bash
      env:
        PROJECT: ${{ inputs.project }}
        RELEASE_VERSION_INPUT: ${{ inputs.release-version }}
        VERSION_OR_UNSTABLE: ${{ github.ref_type == 'tag' && inputs.release-version || 'unstable' }}
      run: |
        set -euo pipefail

        case "$PROJECT" in
          vikunja|veans) ;;
          *)
            echo "::error::Unknown project '$PROJECT'. Expected 'vikunja' or 'veans'." >&2
            exit 1
            ;;
        esac

        case "$PROJECT" in
          vikunja)
            output_dir="."
            dist_prefix="dist"
            ;;
          veans)
            output_dir="veans"
            dist_prefix="veans/dist"
            ;;
        esac

        {
          echo "PROJECT=$PROJECT"
          echo "RELEASE_VERSION=$RELEASE_VERSION_INPUT"
          echo "VERSION_OR_UNSTABLE=$VERSION_OR_UNSTABLE"
          echo "XGO_OUT_NAME=${PROJECT}-${VERSION_OR_UNSTABLE}"
          echo "OUTPUT_DIR=$output_dir"
          echo "DIST_PREFIX=$dist_prefix"
          echo "S3_TARGET_PATH=/${PROJECT}/${VERSION_OR_UNSTABLE}"
          echo "ARTIFACT_BINARIES_NAME=${PROJECT}_bins"
          echo "ARTIFACT_ZIPS_NAME=${PROJECT}_bin_packages"
        } >> "$GITHUB_ENV"

    - name: Download Mage binary
      uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
      with:
        name: mage_bin

    - name: Make mage-static executable
      shell: bash
      run: chmod +x ./mage-static

    - name: Download frontend dist (vikunja only)
      if: inputs.project == 'vikunja'
      uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
      with:
        name: frontend_dist
        path: frontend/dist

    - name: Generate config.yml.sample (vikunja only)
      if: inputs.project == 'vikunja'
      shell: bash
      run: ./mage-static generate:config-yaml 1

    - name: Install upx
      shell: bash
      run: |
        set -euo pipefail
        wget -q https://github.com/upx/upx/releases/download/v5.0.0/upx-5.0.0-amd64_linux.tar.xz
        echo 'b32abf118d721358a50f1aa60eacdbf3298df379c431c3a86f139173ab8289a1  upx-5.0.0-amd64_linux.tar.xz' > upx-5.0.0-amd64_linux.tar.xz.sha256
        sha256sum -c upx-5.0.0-amd64_linux.tar.xz.sha256
        tar xf upx-5.0.0-amd64_linux.tar.xz
        sudo mv upx-5.0.0-amd64_linux/upx /usr/local/bin

    - name: Setup xgo cache
      uses: useblacksmith/cache@71c7c918062ba3861252d84b07fe5ab2a6b467a6 # v5
      with:
        path: /home/runner/.xgo-cache
        key: xgo-${{ inputs.project }}-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          xgo-${{ inputs.project }}-

    - name: Install mage for the build module
      shell: bash
      run: go install github.com/magefile/mage@v1.17.2

    - name: Build release artifacts
      shell: bash
      env:
        RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
        XGO_OUT_NAME: ${{ env.XGO_OUT_NAME }}
        PROJECT: ${{ env.PROJECT }}
      run: |
        set -euo pipefail
        export PATH="$PATH:$(go env GOPATH)/bin"
        cd build && mage release:build "$PROJECT"

    - name: GPG setup
      uses: kolaente/action-gpg@main
      with:
        gpg-passphrase: ${{ inputs.gpg-passphrase }}
        gpg-sign-key: ${{ inputs.gpg-sign-key }}

    - name: Sign zips
      shell: bash
      env:
        DIST_PREFIX: ${{ env.DIST_PREFIX }}
        RELEASE_GPG_PASSPHRASE: ${{ inputs.gpg-passphrase }}
      run: |
        set -euo pipefail
        zip_dir="${DIST_PREFIX}/zip"
        echo "=== GPG agent status ==="
        gpg-connect-agent 'keyinfo --list' /bye || true
        echo "=== GPG secret keys ==="
        gpg -K --with-keygrip
        echo "=== GPG public keys ==="
        gpg --list-keys
        echo "=== Signing files in $zip_dir ==="
        ls -hal "$zip_dir"/*
        for file in "$zip_dir"/*; do
          gpg -v \
            --default-key 7D061A4AA61436B40713D42EFF054DACD908493A \
            -b --batch --yes \
            --passphrase "$RELEASE_GPG_PASSPHRASE" \
            --pinentry-mode loopback \
            --sign "$file"
        done

    - name: Upload zips to S3
      uses: kolaente/s3-action@main
      with:
        s3-access-key-id: ${{ inputs.s3-access-key-id }}
        s3-secret-access-key: ${{ inputs.s3-secret-access-key }}
        s3-endpoint: ${{ inputs.s3-endpoint }}
        s3-bucket: ${{ inputs.s3-bucket }}
        s3-region: ${{ inputs.s3-region }}
        target-path: ${{ env.S3_TARGET_PATH }}
        files: ${{ env.DIST_PREFIX }}/zip/*
        strip-path-prefix: ${{ env.DIST_PREFIX }}/zip/

    - name: Store binaries
      uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
      with:
        name: ${{ env.ARTIFACT_BINARIES_NAME }}
        path: ./${{ env.DIST_PREFIX }}/binaries/*

    - name: Store binary packages
      if: github.ref_type == 'tag'
      uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
      with:
        name: ${{ env.ARTIFACT_ZIPS_NAME }}
        path: ./${{ env.DIST_PREFIX }}/zip/*
