name: NPM

# About this workflow:
# It is triggered on push events to branches production and testing. Then it performs a checkout of the current repo
# and sets up a node environment (v12). Following, it will run `npm ci` to build the package. Next, it will look at your
# commit message, if it includes '#patch', '#minor', or '#major' it will bump the package version accordingly.
# Finally, the `npm publish` command will be run, when on branch testing it will run `npm publish --tag beta` to publish
# it under the beta flag on npm. Note: if no '#patch', '#minor', or '#major' flag is present in the latest commit
# AND the package version is not bumped manually the publish step will fail because we can not publish to an existing
# version.

# GitHub repo configuration:
# 1. Go to Manage access and add 'Github Actions' team with role: admin.
# 2. If you have protected branches, go to Branches > edit protected branch > enable 'Restrict who can push to
#    matching branches' and add the 'athombv/github-actions' team.

# Required secrets:
# - NPM_AUTH_TOKEN: required for publishing to npm
# - SLACK_WEBHOOK_URL: required for posting a message in #software
# - HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN: required when using `npm version` to commit and push to protected
#   branch. If pushing to a non-protected branch replace HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN with GITHUB_TOKEN

# Optional secrets:
# - SSH_KEY: required if `npm ci` needs to install private npm packages

# Note: make sure to commit package-lock.json, this is needed for `npm ci`.

# Note: add `.github` to .npmignore

# Note: when publishing a scoped npm package (e.g. @athombv/node-my-package) append `--access public` to the `npm publish` command, by default scoped packages are published privately.
# For more information see: https://docs.npmjs.com/creating-and-publishing-an-org-scoped-package

# Defines the trigger for this action, in general you want it to run when pushing to production | testing. For more
# information see: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#about-workflow-events)
on:
  push:
    branches:
      - production
      - testing
  workflow_dispatch:
    inputs:
      versionBumpType:
        description: 'Version bump (major, minor or patch)'
        required: true

jobs:
  npm_version_bump_and_publish:
    name: Update version and publish

    # Only run this job if initiator is not the Homey Github Actions Bot to prevent loops and if a version bump is provided
    if: github.actor != 'homey-bot' && (github.event.inputs.versionBumpType == 'patch' || github.event.inputs.versionBumpType == 'minor' || github.event.inputs.versionBumpType == 'major' || contains(github.event.head_commit.message, '#patch') || contains(github.event.head_commit.message, '#minor') || contains(github.event.head_commit.message, '#major'))

    runs-on: ubuntu-latest
    steps:
    
      # Checks out the current repository.
      - name: Checkout git repository
        uses: actions/checkout@v2
        with:
          # The token below is only necessary if you want to push the version bump to a protected branch
          token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}

      # Set git config to reflect Homey Github Actions Bot user
      - name: Set up HomeyGithubActionsBot git user
        run: |
          git config --local user.email "sysadmin+githubactions@athom.com"
          git config --local user.name "Homey Github Actions Bot"

      # Configures a Node.js environment.
      - name: Set up node 12 environment
        uses: actions/setup-node@v1
        with:
          node-version: '12'
          # Needed for publishing to npm
          registry-url: 'https://registry.npmjs.org'

      # Set SSH key
      - uses: webfactory/ssh-agent@v0.4.1
        env:
          SSH_KEY: ${{ secrets.SSH_KEY }}
        if: env.SSH_KEY != null
        with:
          ssh-private-key: ${{ env.SSH_KEY }}

      # Run `npm ci` to re-create your local environment (make sure to commit your package-lock.json!).
      - name: Build
        run: npm ci

      - name: Version bump patch
        if: github.event.inputs.versionBumpType == 'patch' || contains(github.event.head_commit.message, '#patch') && !contains(github.event.head_commit.message, '#minor') && !contains(github.event.head_commit.message, '#major')
        run: |
          npm version patch
          git pull
          git push --follow-tags

      - name: Version bump minor
        if: github.event.inputs.versionBumpType == 'minor' || contains(github.event.head_commit.message, '#minor') && !contains(github.event.head_commit.message, '#major')
        run: |
          npm version minor
          git pull
          git push --follow-tags

      - name: Version bump major
        if: github.event.inputs.versionBumpType == 'major' || contains(github.event.head_commit.message, '#major')
        run: |
          npm version major
          git pull
          git push --follow-tags

      # Publish when this action is running on branch production (when publishing a scoped package add --access public)
      - name: Publish
        if: github.ref == 'refs/heads/production'
        run: |
          npm publish
          VERSION="$(node -p "require('./package.json').version")"
          echo package_version=${VERSION} >> $GITHUB_ENV
          echo $package_version
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}

      # Publish to beta when this action is running on branch testing (when publishing a scoped package add --access public)
      - name: Publish to beta
        if: github.ref == 'refs/heads/testing'
        run: |
          npm publish --tag beta
          VERSION="$(node -p "require('./package.json').version")@beta"
          echo package_version=${VERSION} >> $GITHUB_ENV
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}

      # Post a Slack notification in #software on success/failure
      - name: Slack notify
        if: always()
        uses: innocarpe/actions-slack@v1
        with:
          status: ${{ job.status }}
          success_text: '${{github.repository}} - published v${{env.package_version}} to npm 🚀'
          failure_text: '${{github.repository}} - failed to publish to npm'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Required
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # Required
