# This action looks at the commit history since the last release, and uses
# this to decide which submodules require an update:
on:
  push:
    branches:
      - master
name: release-please-submodule
jobs:
  # This logic looks at commits that have occurred since GitHub's magic
  # latestRelease:
  # https://developer.github.com/v3/repos/releases/#get-the-latest-release
  # TODO: it would be better if we retrieved a list of all prior releases,
  # and found the oldest release within the SUB_MODULES array. We need this
  # logic for other libraries as well, and would like to pull this logic
  # into its own action.
  changeFinder:
    runs-on: ubuntu-latest
    outputs:
      submodules: ${{ steps.interrogate.outputs.submodules }}
    steps:
      - uses: actions/checkout@v2
      - id: interrogate
        uses: actions/github-script@v3
        with:
            github-token: ${{secrets.GITHUB_TOKEN}}
            script: |
              const {execSync} = require('child_process');
              const SUB_MODULES = [
                'bigtable',
                'bigquery',
                'datastore',
                'firestore',
                'logging',
                'pubsub',
                'pubsublite',
                'spanner',
                'storage',
              ];
              const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
              const latestRelease = await github.repos.getLatestRelease({
                owner,
                repo
              });
              console.info(`latest release: ${latestRelease.data.tag_name}`);
              // pull all tags, so we can get diff between HEAD and last release:
              execSync('git pull --tags');
              execSync(`git reset --hard ${latestRelease.data.tag_name}`);
              const status = execSync(`git diff --name-only origin/master`, { encoding: 'utf-8'});
              console.info(status);
              const changes = status.split('\n');
              const submodules = new Set();
              for (const change of changes) {
                const library = change.split('/')[0];
                console.info(`update to path ${library}`);
                if (SUB_MODULES.includes(library)) {
                  submodules.add(library);
                }
              }
              console.log(`::set-output name=submodules::${JSON.stringify(Array.from(submodules))}`);
  release-pr: # Create the release PR based on commit history:
    runs-on: ubuntu-latest
    needs: changeFinder
    strategy:
      fail-fast: false
      matrix:
        package: ${{fromJson(needs.changeFinder.outputs.submodules)}}
    steps:
      - uses: GoogleCloudPlatform/release-please-action@v2
        id: release-please
        with:
           path: ${{ matrix.package }}
           token: ${{ secrets.FORKING_TOKEN }}
           fork: true
           release-type: go
           package-name: ${{ matrix.package }}
           monorepo-tags: true
           command: release-pr
      - uses: actions/github-script@v3
        id: label # Adds the "autorelease: pending" label.
        if: ${{steps.release-please.outputs.pr}}
        with:
            github-token: ${{secrets.GITHUB_TOKEN}}
            script: |
              const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
              const latestRelease = await github.issues.addLabels({
                owner,
                repo,
                issue_number: ${{steps.release-please.outputs.pr}},
                labels: ['autorelease: pending']
              });
              console.log(`Tagged ${{steps.release-please.outputs.pr}}`)
  release-please-release: # Actually create a release tag.
    runs-on: ubuntu-latest
    needs: changeFinder
    strategy:
      fail-fast: false
      matrix:
        package: ${{fromJson(needs.changeFinder.outputs.submodules)}}
    steps:
      - uses: GoogleCloudPlatform/release-please-action@v2
        id: tag-release
        with:
          path: ${{ matrix.package }}
          changelog-path: CHANGES.md
          token: ${{ secrets.GITHUB_TOKEN }}
          release-type: go
          monorepo-tags: true
          package-name: ${{ matrix.package }}
          command: github-release
      # Add the "autorelease: published" and remove tagged, this allows
      # monitoring to be enabled that detects failed releases:
      - uses: actions/github-script@v3
        id: untag-release
        if: ${{steps.tag-release.outputs.pr}}
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
            await github.issues.addLabels({
              owner,
              repo,
              issue_number: ${{steps.tag-release.outputs.pr}},
              labels: ['autorelease: published']
            });
            github.issues.removeLabel({
              owner,
              repo,
              issue_number: ${{steps.tag-release.outputs.pr}},
              name: 'autorelease: tagged',
            });
            console.log(`Tagged ${{steps.tag-release.outputs.pr}}`)
