name: goreleaser

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write  # publishing releases
  repository-projects: write  # move cards between columns

jobs:
  goreleaser:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Set up Go 1.19
        uses: actions/setup-go@v3
        with:
          go-version: 1.19
      - name: Generate changelog
        id: changelog
        run: |
          echo "::set-output name=tag-name::${GITHUB_REF#refs/tags/}"
          gh api repos/$GITHUB_REPOSITORY/releases/generate-notes \
            -f tag_name="${GITHUB_REF#refs/tags/}" \
            -f target_commitish=trunk \
            -q .body > CHANGELOG.md
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
      - name: Install osslsigncode
        run: sudo apt-get install -y osslsigncode
      - name: Obtain signing cert
        run: |
          cert="$(mktemp -t cert.XXX)"
          base64 -d <<<"$CERT_CONTENTS" > "$cert"
          echo "CERT_FILE=$cert" >> $GITHUB_ENV
        env:
          CERT_CONTENTS: ${{ secrets.WINDOWS_CERT_PFX }}
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v4
        with:
          version: "~1.13.1"
          args: release --release-notes=CHANGELOG.md
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
          GORELEASER_CURRENT_TAG: ${{steps.changelog.outputs.tag-name}}
          CERT_PASSWORD: ${{secrets.WINDOWS_CERT_PASSWORD}}
      - name: Checkout documentation site
        uses: actions/checkout@v3
        with:
          repository: github/cli.github.com
          path: site
          fetch-depth: 0
          ssh-key: ${{secrets.SITE_SSH_KEY}}
      - name: Update site man pages
        env:
          GIT_COMMITTER_NAME: cli automation
          GIT_AUTHOR_NAME: cli automation
          GIT_COMMITTER_EMAIL: noreply@github.com
          GIT_AUTHOR_EMAIL: noreply@github.com
        run: make site-bump
      - name: Move project cards
        continue-on-error: true
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
          PENDING_COLUMN: 8189733
          DONE_COLUMN: 7110130
        run: |
          api() { gh api -H 'accept: application/vnd.github.inertia-preview+json' "$@"; }
          api-write() { [[ $GITHUB_REF == *-* ]] && echo "skipping: api $*" || api "$@"; }
          cards=$(api --paginate projects/columns/$PENDING_COLUMN/cards | jq ".[].id")
          for card in $cards; do
            api-write --silent projects/columns/cards/$card/moves -f position=top -F column_id=$DONE_COLUMN
          done
          echo "moved ${#cards[@]} cards to the Done column"
      - name: Install packaging dependencies
        run: sudo apt-get install -y rpm reprepro
      - name: Set up GPG
        run: |
          echo "${{secrets.GPG_PUBKEY}}" | base64 -d | gpg --import --no-tty --batch --yes
          echo "${{secrets.GPG_KEY}}" | base64 -d | gpg --import --no-tty --batch --yes
          echo "allow-preset-passphrase" > ~/.gnupg/gpg-agent.conf
          gpg-connect-agent RELOADAGENT /bye
          echo "${{secrets.GPG_PASSPHRASE}}" | /usr/lib/gnupg2/gpg-preset-passphrase --preset "${{secrets.GPG_KEYGRIP}}"
      - name: Sign RPMs
        run: |
          cp script/rpmmacros ~/.rpmmacros
          rpmsign --addsign dist/*.rpm
      - name: Run createrepo
        run: |
          mkdir -p site/packages/rpm
          cp dist/*.rpm site/packages/rpm/
          ./script/createrepo.sh
          cp -r dist/repodata site/packages/rpm/
          pushd site/packages/rpm
          gpg --yes --detach-sign --armor repodata/repomd.xml
          popd
      - name: Run reprepro
        env:
          # We are no longer adding to the distribution list.
          # All apt distributions should use "stable" according to our install documentation.
          # In the future we will remove legacy distributions listed here.
          RELEASES: "cosmic eoan disco groovy focal stable oldstable testing sid unstable buster bullseye stretch jessie bionic trusty precise xenial hirsute impish kali-rolling"
        run: |
          mkdir -p upload
          for release in $RELEASES; do
            for file in dist/*.deb; do
              reprepro --confdir="+b/script" includedeb "$release" "$file"
            done
          done
          cp -a dists/ pool/ upload/
          mkdir -p site/packages
          cp -a upload/* site/packages/
      - name: Publish site
        env:
          GIT_COMMITTER_NAME: cli automation
          GIT_AUTHOR_NAME: cli automation
          GIT_COMMITTER_EMAIL: noreply@github.com
          GIT_AUTHOR_EMAIL: noreply@github.com
        working-directory: ./site
        run: |
          git add packages
          git commit -m "Add rpm and deb packages for ${GITHUB_REF#refs/tags/}"
          if [[ $GITHUB_REF == *-* ]]; then
            git log --oneline @{upstream}..
            git diff --name-status @{upstream}..
          else
            git push
          fi

  msi:
    needs: goreleaser
    runs-on: windows-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Download gh.exe
        id: download_exe
        shell: bash
        run: |
          hub release download "${GITHUB_REF#refs/tags/}" -i '*windows_amd64*.zip'
          printf "::set-output name=zip::%s\n" *.zip
          unzip -o *.zip && rm -v *.zip
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
      - name: Prepare PATH
        id: setupmsbuild
        uses: microsoft/setup-msbuild@v1.3.1
      - name: Build MSI
        id: buildmsi
        shell: bash
        env:
          ZIP_FILE: ${{ steps.download_exe.outputs.zip }}
          MSBUILD_PATH: ${{ steps.setupmsbuild.outputs.msbuildPath }}
        run: |
          name="$(basename "$ZIP_FILE" ".zip")"
          version="$(echo -e ${GITHUB_REF#refs/tags/v} | sed s/-.*$//)"
          "${MSBUILD_PATH}\MSBuild.exe" ./build/windows/gh.wixproj -p:SourceDir="$PWD" -p:OutputPath="$PWD" -p:OutputName="$name" -p:ProductVersion="$version"
      - name: Obtain signing cert
        id: obtain_cert
        shell: bash
        run: |
          base64 -d <<<"$CERT_CONTENTS" > ./cert.pfx
          printf "::set-output name=cert-file::%s\n" ".\\cert.pfx"
        env:
          CERT_CONTENTS: ${{ secrets.WINDOWS_CERT_PFX }}
      - name: Sign MSI
        env:
          CERT_FILE: ${{ steps.obtain_cert.outputs.cert-file }}
          EXE_FILE: ${{ steps.buildmsi.outputs.msi }}
          CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }}
        run: .\script\signtool sign /d "GitHub CLI" /f $env:CERT_FILE /p $env:CERT_PASSWORD /fd sha256 /tr http://timestamp.digicert.com /v $env:EXE_FILE
      - name: Upload MSI
        shell: bash
        run: |
          tag_name="${GITHUB_REF#refs/tags/}"
          hub release edit "$tag_name" -m "" -a "$MSI_FILE"
          release_url="$(gh api repos/:owner/:repo/releases -q ".[]|select(.tag_name==\"${tag_name}\")|.url")"
          publish_args=( -F draft=false )
          if [[ $GITHUB_REF != *-* ]]; then
            publish_args+=( -f discussion_category_name="$DISCUSSION_CATEGORY" )
          fi
          gh api -X PATCH "$release_url" "${publish_args[@]}"
        env:
          MSI_FILE: ${{ steps.buildmsi.outputs.msi }}
          DISCUSSION_CATEGORY: General
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
      - name: Bump homebrew-core formula
        uses: mislav/bump-homebrew-formula-action@v2
        if: "!contains(github.ref, '-')" # skip prereleases
        with:
          formula-name: gh
        env:
          COMMITTER_TOKEN: ${{ secrets.UPLOAD_GITHUB_TOKEN }}
      - name: Checkout scoop bucket
        uses: actions/checkout@v3
        with:
          repository: cli/scoop-gh
          path: scoop-gh
          fetch-depth: 0
          token: ${{secrets.UPLOAD_GITHUB_TOKEN}}
      - name: Bump scoop bucket
        shell: bash
        run: |
          hub release download "${GITHUB_REF#refs/tags/}" -i '*_checksums.txt'
          script/scoop-gen "${GITHUB_REF#refs/tags/}" ./scoop-gh/gh.json < *_checksums.txt
          git -C ./scoop-gh commit -m "gh ${GITHUB_REF#refs/tags/}" gh.json
          if [[ $GITHUB_REF == *-* ]]; then
            git -C ./scoop-gh show -m
          else
            git -C ./scoop-gh push
          fi
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
          GIT_COMMITTER_NAME: cli automation
          GIT_AUTHOR_NAME: cli automation
          GIT_COMMITTER_EMAIL: noreply@github.com
          GIT_AUTHOR_EMAIL: noreply@github.com
