name: Release
run-name: Release (${{ inputs.type }})

# Single entry point for all releases. Trusted publishing on npmjs.com
# validates the filename of the top-level workflow of the run, and only one
# trusted publisher configuration is allowed per package, so every release
# must start from this workflow. The trusted publisher config on npmjs.com
# must name release.yml as the workflow filename.
#
# If the npm_publish job fails after the release job succeeded (e.g. a
# transient registry error), recover with 'Re-run failed jobs' on the failed
# run. Do NOT dispatch a new release: the version bump has already been
# committed and pushed, so a fresh dispatch would bump the version again and
# leave the previous version unpublished on npm.
on:
  workflow_dispatch:
    inputs:
      type:
        # No default: an input-less API/CLI dispatch must fail (422) rather
        # than silently run a release; the UI dropdown still works.
        description: 'Release type'
        required: true
        type: choice
        options:
          - patch
          - feature

# Serialize releases: overlapping runs would race their pushes to master and
# unstable and could publish an untagged tree.
concurrency:
  group: release
  cancel-in-progress: false

jobs:
  patch-release:
    if: ${{ inputs.type == 'patch' }}
    runs-on: ubuntu-latest
    timeout-minutes: 60
    environment: prod
    steps:
      - name: Set branch name
        shell: bash
        run: |
          echo "BRANCH=master" >> $GITHUB_ENV
          echo "Branch: master"
      - name: checkout patch branch
        uses: actions/checkout@v7
        with:
          ref: ${{ env.BRANCH }}
      - uses: actions/setup-node@v7
        with:
          node-version-file: .nvmrc
          cache: 'npm'
      - name: Install dependencies
        run: npm install
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run tests
        run : |
          npm test
      - name: Get new version string
        id: get_new_patch_version
        run: |
          chmod +rx ./.github/workflows/scripts/new-patch-version.sh
          . ./.github/workflows/scripts/new-patch-version.sh
        shell: bash
      - name: See patch branch
        run: echo branch ${{ env.BRANCH }}
        shell: bash
      - name: See new patch version
        run: echo "# version:" ${{ env.VERSION }}
        shell: bash
      - name: checkout master branch
        uses: actions/checkout@v7
        with:
          ref: master
          fetch-depth: 0
      - name: Set Git Config
        run : |
          # Set git configs
          git config --global user.name "${GITHUB_ACTOR}"
          git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
      - name: Update Version on master
        id: update_backport_version_master
        run: |
          jq --arg ver "${{ env.VERSION }}" '.versions += [$ver]' ./documentation/versions.json >> /tmp/temp.json
          mv /tmp/temp.json ./documentation/versions.json

          git add . && git commit -m "Docs: Add ${{ env.VERSION }} to versions.json"
          git push
      - name: checkout unstable branch
        uses: actions/checkout@v7
        with:
          ref: unstable
          fetch-depth: 0
      - name: Update Version on unstable
        id: update_backport_version_unstable
        run: |
          jq --arg ver "${{ env.VERSION }}" '.versions += [$ver]' ./documentation/versions.json >> /tmp/temp.json
          mv /tmp/temp.json ./documentation/versions.json

          git add . && git commit -m "Docs: Add ${{ env.VERSION }} to versions.json"
          git push
          git checkout ${{ env.BRANCH }}
      - name: Set Git Config
        run : |
          # Set git configs
          git config --global user.name "${GITHUB_ACTOR}"
          git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
      - name: Make Release
        id: release
        run: |
          chmod +rx .github/workflows/scripts/pre_release_test.sh
          . .github/workflows/scripts/pre_release_test.sh ${{ env.BRANCH }}
      - name: Archive action failure results
        uses: actions/upload-artifact@v7
        if: ${{ failure() && steps.release.conclusion == 'failure' }}
        with:
          name: npm-release--failure-report
          path: /home/runner/.npm/_logs/
      - name: Publish Package to GitHub Releases
        run: |
          curl -L \
          -X POST \
          -H "Accept: application/vnd.github+json" \
          -H "Authorization: Bearer ${{ secrets.MAIN_GH_TOKEN }}" \
          -H "X-GitHub-Api-Version: 2022-11-28" \
          https://api.github.com/repos/${{ github.repository }}/releases \
          -d '{"tag_name":"v${{ env.VERSION }}","target_commitish":"master","name":"v${{ env.VERSION }}","body":"Release version v${{ env.VERSION }}","draft":false,"prerelease":false,"generate_release_notes":false}'
      - name: Deploy to Github Pages 🚀
        if: ${{ env.BRANCH == 'master' }}
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          folder: documentation

  feature-release:
    if: ${{ inputs.type == 'feature' }}
    runs-on: ubuntu-latest
    environment: prod
    timeout-minutes: 60
    steps:
      - name: checkout unstable branch
        uses: actions/checkout@v7
        with:
          ref: 'unstable'
          fetch-depth: 0
      - uses: actions/setup-node@v7
        with:
          node-version-file: .nvmrc
          cache: 'npm'
      - name: Install dependencies
        run: npm install
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run tests
        run : |
          npm test
      - name: Determine version for the release
        id: get_new_patch_version
        run: |
          pwd
          chmod 777 -R ./* ./.[!.]*
          . ./.github/workflows/scripts/new-feature-version.sh
        shell: bash
      - name: See new master version and jq version
        run: |
          echo VERSION ${{ env.VERSION }}
          jq --version
        shell: bash
      - name: Checkout Master Branch
        uses: actions/checkout@v7
        with:
          ref: master
          fetch-depth: 0
      - name: Update documentation and Merge unstable to master branch
        run: |
          . ./.github/workflows/scripts/merge_unstable_to_master.sh
      - name: Build release and verify changes
        id: release
        run: |
          . .github/workflows/scripts/pre_release_test.sh master
      - name: Archive code coverage results
        uses: actions/upload-artifact@v7
        if: ${{ failure() && steps.release.conclusion == 'failure' }}
        with:
          name: npm-release--failure-report
          path: /home/runner/.npm/_logs/
      - name: Publish Package to GitHub Releases
        run: |
          curl -L \
          -X POST \
          -H "Accept: application/vnd.github+json" \
          -H "Authorization: Bearer ${{ secrets.MAIN_GH_TOKEN }}" \
          -H "X-GitHub-Api-Version: 2022-11-28" \
          https://api.github.com/repos/${{ github.repository }}/releases \
          -d '{"tag_name":"v${{ env.VERSION }}","target_commitish":"master","name":"v${{ env.VERSION }}","body":"Release version v${{ env.VERSION }}","draft":false,"prerelease":false,"generate_release_notes":false}'
      - name: Deploy to Github Pages 🚀
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          folder: documentation
      - name: Create Issue
        run: |
          TITLE="Create a blog post for release v$VERSION"
          echo "Issue title: $TITLE"
          sed ':a;N;$!ba;s/\n/\\n/g' ./.github/workflows/md/blog-issue-template.md > output_file.txt
          BODY="$(cat output_file.txt)"

          echo "Body: $BODY"

          curl -X POST \
              -H "Authorization: token ${{ secrets.CYTOSCAPE_JS_BLOG_TOKEN }}" \
              -H "Accept: application/vnd.github.v3+json" \
              "https://api.github.com/repos/cytoscape/cytoscape.js-blog/issues" \
              -d "{\"title\":\"$TITLE\",\"body\":\"$BODY\"}"

  # Exactly one of the release jobs above runs per dispatch; publish after
  # whichever one ran, but not if it failed or the run was cancelled.
  npm_publish:
    needs: [patch-release, feature-release]
    if: ${{ !cancelled() && (needs.patch-release.result == 'success' || needs.feature-release.result == 'success') }}
    permissions:
      contents: read
      id-token: write
    uses: ./.github/workflows/npm-publish.yml
