#
# This GitHub action triggers a fresh set of Packer builds
# and publishes them to GitHub Releases under the `nightly` tag.
# Note that artifacts available via GitHub Releases are not codesigned or notarized.
# Failures are reported to slack.
#

name: Nightly Release

on:
  schedule:
    # Runs against the default branch every day at midnight
    - cron: "0 0 * * *"
  workflow_dispatch:

permissions:
  contents: write

jobs:
  # Build a fresh set of artifacts
  build-artifacts:
    uses: hashicorp/packer/.github/workflows/build.yml@main
  github-release:
    needs: build-artifacts
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
      - name: Download built artifacts
        uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
        with:
          path: out/
      # Set BUILD_OUTPUT_LIST to out\<project>-<version>.<fileext>\*,out\...
      # This is needed to attach the build artifacts to the GitHub Release
      - name: Set BUILD_OUTPUT_LIST
        run: |
          echo "$(ls -xm1 out/)" > tmp.txt
          cat tmp.txt | sed 's:.*:out/&/*:' > tmp2.txt
          echo "BUILD_OUTPUT_LIST=$(cat tmp2.txt | tr '\n' ',' | perl -ple 'chop')" >> $GITHUB_ENV
          rm -rf tmp.txt && rm -rf tmp2.txt
      - name: Advance nightly tag
        uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            try {
                await github.rest.git.deleteRef({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  ref: "tags/nightly"
                })
            } catch (e) {
              console.log("Warning: The nightly tag doesn't exist yet, so there's nothing to do. Trace: " + e)
            }
            await github.rest.git.createRef({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: "refs/tags/nightly",
              sha: context.sha
            })
      # This will create a new GitHub Release called `nightly`
      # If a release with this name already exists, it will overwrite the existing data
      - name: Create a nightly GitHub prerelease
        id: create_prerelease
        continue-on-error: true
        uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
        with:
          name: nightly
          artifacts: "${{ env.BUILD_OUTPUT_LIST }}"
          tag: nightly
          bodyFile: ".github/workflows/nightly-release-readme.md"
          prerelease: true
          allowUpdates: true
          removeArtifacts: true
          draft: false
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Store GitHub Release ID
        if: steps.create_prerelease.outcome == 'success'
        run: |
          echo "prerelease_id=${{ steps.create_prerelease.outputs.id }}" >> $GITHUB_ENV
      - name: Sleep before retry
        id: sleep_before_retry
        if: steps.create_prerelease.outcome == 'failure'
        run : sleep 30m
        shell: bash
      - name: Retry failed nightly GitHub prerelease
        id: create_prerelease_retry
        if: steps.create_prerelease.outcome == 'failure'
        uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
        with:
          name: nightly
          artifacts: "${{ env.BUILD_OUTPUT_LIST }}"
          tag: nightly
          bodyFile: ".github/workflows/nightly-release-readme.md"
          prerelease: true
          allowUpdates: true
          removeArtifacts: true
          draft: false
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Store Updated GitHub Release ID 
        if: steps.create_prerelease_retry.outcome == 'success'
        run: |
          echo "prerelease_id=${{ steps.create_prerelease_retry.outputs.id }}" >> $GITHUB_ENV
      - name: Publish nightly GitHub prerelease
        uses: eregon/publish-release@46913fa2b3f7edc7345ae3c17f6d1b093a54916d # v1.0.5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          release_id: ${{ env.prerelease_id }}
  # Send a slack notification if either job defined above fails
  slack-notify:
    permissions:
      contents: none
    needs:
      - build-artifacts
      - github-release
    if: always() && (needs.build-artifacts.result == 'failure' || needs.github-release.result == 'failure')
    runs-on: ubuntu-latest
    steps:
      - name: Send slack notification on failure
        uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0
        with:
          payload: |
            {
              "text": ":alert: Packer Nightly Release *FAILED* :alert:",
              "attachments": [
                {
                  "color": "#C41E3A",
                  "blocks": [
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "Branch: `${{ github.ref_name }}`\nRef: ${{ github.sha }}\nWorkflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
                      }
                    }
                  ]
                }
              ]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
