name: draft-release

on:
  workflow_dispatch:

jobs:
  draft-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - name: Install jq
        run: |
          mkdir -p deps/bin
          curl -s -L -o deps/bin/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
          chmod +x deps/bin/jq
          echo "${PWD}/deps/bin" >> $GITHUB_PATH
      - name: Derive lifecycle version from branch name
        run: |
          [[ $GITHUB_REF =~ ^refs\/heads\/release/(.*)$ ]] && version=${BASH_REMATCH[1]}
          if [[ -z "${version}" ]]; then
            echo "lifecycle version not detected."
            exit 1
          fi
          echo "LIFECYCLE_VERSION=$version" >> $GITHUB_ENV
      - name: Determine download urls for linux-x86-64, linux-arm64, linux-ppc64le, linux-s390x, and windows
        id: artifact-urls
        # FIXME: this script should be updated to work with actions/github-script@v6
        uses: actions/github-script@v3
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            return github.actions
              .listRepoWorkflows({
                 owner: "${{ github.repository_owner }}",
                 repo: "lifecycle",
              })
              .then(workflows_result => {
                let workflows = workflows_result.data.workflows
                  .filter(a => a.name === "build" && a.state === "active")
                  .map(a => a.id);
                if (workflows.length === 0) {
                  throw "no active workflows found with name build"
                }
                return workflows[0]
              })
              .then(workflow_id => {
                return github.actions.listWorkflowRunsForRepo({
                  owner: "${{ github.repository_owner }}",
                  repo: "lifecycle",
                  workflow_id: workflow_id,
                  branch: "release/${{ env.LIFECYCLE_VERSION }}",
                  event: "push"
                })
              })
              .then(workflow_runs_result => {
                let workflow_runs = workflow_runs_result.data.workflow_runs
                  .filter(run => run.conclusion === "success")
                  .filter(run => run.head_sha === "${{ github.sha }}");
                if (workflow_runs.length === 0) {
                  throw "no successful workflow runs found for commit"
                }
                return workflow_runs[0].id
              })
              .then(workflow_runid => {
                return github.actions.listWorkflowRunArtifacts({
                  owner: "${{ github.repository_owner }}",
                  repo: "lifecycle",
                  run_id: workflow_runid
                })
              })
              .then(artifacts_result => {
                let tuples = artifacts_result.data.artifacts
                  .map(artifact => [artifact.name, artifact.archive_download_url]);
                let urlList = new Array();
                tuples.forEach(function(tuple) {
                  if (tuple[0].includes("lifecycle-")) {
                      urlList.push(tuple[1]);
                  }
                })
                if (urlList.length === 0) {
                  throw "no artifacts found"
                }
                if (urlList.length != 12) {
                  throw "there should be exactly 12 artifacts"
                }
                return urlList.join(",")
              })
      - name: Download artifacts
        run: |
          mkdir artifacts
          echo "ARTIFACTS_PATH=$PWD/artifacts" >> $GITHUB_ENV

          urls=$(echo '${{ steps.artifact-urls.outputs.result }}' | jq -r . )

          for url in $(echo $urls | tr "," "\n"); do
            curl -sL -w 'RESP_CODE:%{response_code}\n' \
              --header 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
              -o tmp-artifact.zip $url
            unzip -d artifacts tmp-artifact.zip
            rm tmp-artifact.zip
          done
      - name: Combine checksums
        run: |
          cd ${{ env.ARTIFACTS_PATH }}
          cat *.sha256 | sort > lifecycle-v${{ env.LIFECYCLE_VERSION }}-checksums.txt
          rm *.sha256
      - name: Set pre-release kind
        if: "contains(env.LIFECYCLE_VERSION, 'rc') || contains(env.LIFECYCLE_VERSION, 'pre')" # e.g., 0.99.0-rc.1
        run: |
          echo "RELEASE_KIND=pre-release" >> $GITHUB_ENV
      - name: Set release kind
        if: "!contains(env.LIFECYCLE_VERSION, 'rc') && !contains(env.LIFECYCLE_VERSION, 'pre')"
        run: |
          echo "RELEASE_KIND=release" >> $GITHUB_ENV
      - name: Get previous release tag
        id: get-previous-release-tag
        uses: actions/github-script@v6
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          result-encoding: string
          script: |
            return github.rest.repos.getLatestRelease({
                owner: "buildpacks",
                repo: "lifecycle",
            }).then(result => {
                return result.data.tag_name
            })
      - name: Setup go
        uses: actions/setup-go@v5
        with:
          check-latest: true
          go-version-file: 'go.mod'
      - name: Get go version
        id: get-go-version
        run: |
          mkdir tmp
          tar xzvf ${{ env.ARTIFACTS_PATH }}/lifecycle-v${{ env.LIFECYCLE_VERSION }}+linux.x86-64.tgz -C tmp/
          echo "GO_VERSION=$(go version tmp/lifecycle/lifecycle | cut -d ' ' -f 2 | sed -e 's/^go//')" >> $GITHUB_ENV
      - name: Set release body text
        run: |
          cat << EOF > body.txt
          # lifecycle v${{ env.LIFECYCLE_VERSION }}

          Welcome to v${{ env.LIFECYCLE_VERSION }}, a ${{ env.RELEASE_KIND }} of the Cloud Native Buildpacks Lifecycle.

          ##  Prerequisites

          The lifecycle runs as a normal user in a series of unprivileged containers. To export images and cache image layers, it requires access to a Docker (compatible) daemon **or** an OCI registry.

          ## Install

          Extract the .tgz file and copy the lifecycle binaries into a [build image](https://github.com/buildpacks/spec/blob/main/platform.md#build-image). The build image can then be orchestrated by a platform implementation such as the [pack CLI](https://github.com/buildpack/pack) or [tekton](https://github.com/tektoncd/catalog/tree/main/task/buildpacks).

          ## Lifecycle Image

          An OCI image containing the lifecycle binaries is available at buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}.

          ## Features

          * TODO
          * Updates go to version ${{ env.GO_VERSION }}

          ## Bugfixes

          * TODO

          ## Chores

          * TODO

          **Full Changelog**: https://github.com/buildpacks/lifecycle/compare/${{ steps.get-previous-release-tag.outputs.result }}...release/${{ env.LIFECYCLE_VERSION }}

          ## Contributors

          We'd like to acknowledge that this release wouldn't be as good without the help of the following amazing contributors:

          TODO

          EOF
      - name: Create pre-release
        if: "contains(env.LIFECYCLE_VERSION, 'rc') || contains(env.LIFECYCLE_VERSION, 'pre')" # e.g., 0.99.0-rc.1
        run: |
          cd ${{ env.ARTIFACTS_PATH }}
          gh release create v${{ env.LIFECYCLE_VERSION }} \
            $(ls | sort | paste -sd " " -) \
            --draft \
            --notes-file ../body.txt \
            --prerelease \
            --target $GITHUB_REF \
            --title "lifecycle v${{ env.LIFECYCLE_VERSION }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Create release
        if: "!contains(env.LIFECYCLE_VERSION, 'rc') && !contains(env.LIFECYCLE_VERSION, 'pre')"
        run: |
          cd ${{ env.ARTIFACTS_PATH }}
          gh release create v${{ env.LIFECYCLE_VERSION }} \
            $(ls | sort | paste -sd " " -) \
            --draft \
            --notes-file ../body.txt \
            --target $GITHUB_REF \
            --title "lifecycle v${{ env.LIFECYCLE_VERSION }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
