# Copyright 2020 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Release Candidate

on:
  # Only run the workflow when a PR is updated or when a developer explicitly requests
  # a build by sending a 'firebase_build' event.
  pull_request:
    types: [opened, synchronize, closed]

  repository_dispatch:
    types:
      - firebase_build

jobs:
  stage_release:
    # To publish a release, merge the release PR with the label 'release:publish'.
    # To stage a release without publishing it, send a 'firebase_build' event or apply
    # the 'release:stage' label to a PR.
    if: github.event.action == 'firebase_build' ||
      contains(github.event.pull_request.labels.*.name, 'release:stage') ||
      (github.event.pull_request.merged &&
        contains(github.event.pull_request.labels.*.name, 'release:publish'))

    runs-on: ubuntu-latest

    # When manually triggering the build, the requester can specify a target branch or a tag
    # via the 'ref' client parameter.
    steps:
    - name: Checkout source for staging
      uses: actions/checkout@v4
      with:
        ref: ${{ github.event.client_payload.ref || github.ref }}

    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 18.x

    - name: Install and build
      run: |
        npm ci
        npm run build
        npm run build:tests

    - name: Run unit tests
      run: npm test

    - name: Verify public API
      run: npm run api-extractor

    - name: Run integration tests
      run: ./.github/scripts/run_integration_tests.sh
      env:
        FIREBASE_SERVICE_ACCT_KEY: ${{ secrets.FIREBASE_SERVICE_ACCT_KEY }}
        FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }}
        FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}

    - name: Package release artifacts
      run: |
        npm pack
        mkdir -p dist
        cp *.tgz dist/

    # Attach the packaged artifacts to the workflow output. These can be manually
    # downloaded for later inspection if necessary.
    - name: Archive artifacts
      uses: actions/upload-artifact@v4
      with:
        name: dist
        path: dist

    - name: Verify tarball
      run: |
        PACKAGE_TARBALL=`ls firebase-admin-*.tgz`
        ./.github/scripts/verify_package.sh $PACKAGE_TARBALL

  publish_release:
    needs: stage_release

    # Check whether the release should be published. We publish only when the trigger PR is
    #   1. merged
    #   2. to the master branch
    #   3. with the label 'release:publish', and
    #   4. the title prefix '[chore] Release '.
    if: github.event.pull_request.merged &&
      github.ref == 'refs/heads/master' &&
      contains(github.event.pull_request.labels.*.name, 'release:publish') &&
      startsWith(github.event.pull_request.title, '[chore] Release ')

    runs-on: ubuntu-latest

    steps:
    - name: Checkout source for publish
      uses: actions/checkout@v4

    # Download the artifacts created by the stage_release job.
    - name: Download release candidates
      uses: actions/download-artifact@v4.1.7
      with:
        name: dist
        path: dist

    # Node.js and NPM are needed to complete the publish.
    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 18.x

    - name: Publish preflight check
      id: preflight
      run: ./.github/scripts/publish_preflight_check.sh

    # See: https://cli.github.com/manual/gh_release_create
    - name: Create release tag
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: gh release create ${{ steps.preflight.outputs.version }}
            --title "Firebase Admin Node.js SDK ${{ steps.preflight.outputs.version }}"
            --notes '${{ steps.preflight.outputs.changelog }}'

    - name: Publish to NPM
      run: ./.github/scripts/publish_package.sh
      env:
        NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
        VERSION: ${{ steps.preflight.outputs.version }}

    # Post to Twitter if explicitly opted-in by adding the label 'release:tweet'.
    - name: Post to Twitter
      if: success() &&
        contains(github.event.pull_request.labels.*.name, 'release:tweet')
      uses: ./.github/actions/send-tweet
      with:
        status: >
          ${{ steps.preflight.outputs.version }} of @Firebase Admin Node.js SDK is available.
          https://github.com/firebase/firebase-admin-node/releases/tag/${{ steps.preflight.outputs.version }}
        consumer-key: ${{ secrets.TWITTER_CONSUMER_KEY }}
        consumer-secret: ${{ secrets.TWITTER_CONSUMER_SECRET }}
        access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
        access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
      continue-on-error: true