# This file is automatically added by @npmcli/template-oss. Do not edit.

name: Post Dependabot

on: pull_request

permissions:
  contents: write

jobs:
  template-oss:
    name: template-oss
    if: github.repository_owner == 'npm' && github.actor == 'dependabot[bot]'
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.ref }}
      - name: Setup Git User
        run: |
          git config --global user.email "npm-cli+bot@github.com"
          git config --global user.name "npm CLI robot"
      - name: Setup Node
        uses: actions/setup-node@v4
        id: node
        with:
          node-version: 22.x
          check-latest: contains('22.x', '.x')
      - name: Install Latest npm
        uses: ./.github/actions/install-latest-npm
        with:
          node: ${{ steps.node.outputs.node-version }}
      - name: Install Dependencies
        run: npm i --ignore-scripts --no-audit --no-fund
      - name: Fetch Dependabot Metadata
        id: metadata
        uses: dependabot/fetch-metadata@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}

      # Dependabot can update multiple directories so we output which directory
      # it is acting on so we can run the command for the correct root or workspace
      - name: Get Dependabot Directory
        if: contains(steps.metadata.outputs.dependency-names, '@npmcli/template-oss')
        id: flags
        run: |
          dependabot_dir="${{ steps.metadata.outputs.directory }}"
          if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/main" ]]; then
            echo "workspace=-iwr" >> $GITHUB_OUTPUT
          else
            # strip leading slash from directory so it works as a
            # a path to the workspace flag
            echo "workspace=--workspace ${dependabot_dir#/}" >> $GITHUB_OUTPUT
          fi

      - name: Apply Changes
        if: steps.flags.outputs.workspace
        id: apply
        run: |
          npm run template-oss-apply ${{ steps.flags.outputs.workspace }}
          if [[ `git status --porcelain` ]]; then
            echo "changes=true" >> $GITHUB_OUTPUT
          fi
          # This only sets the conventional commit prefix. This workflow can't reliably determine
          # what the breaking change is though. If a BREAKING CHANGE message is required then
          # this PR check will fail and the commit will be amended with stafftools
          if [[ "${{ steps.metadata.outputs.update-type }}" == "version-update:semver-major" ]]; then
            prefix='feat!'
          else
            prefix='chore'
          fi
          echo "message=$prefix: postinstall for dependabot template-oss PR" >> $GITHUB_OUTPUT

      # This step will fail if template-oss has made any workflow updates. It is impossible
      # for a workflow to update other workflows. In the case it does fail, we continue
      # and then try to apply only a portion of the changes in the next step
      - name: Push All Changes
        if: steps.apply.outputs.changes
        id: push
        continue-on-error: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git commit -am "${{ steps.apply.outputs.message }}"
          git push

      # If the previous step failed, then reset the commit and remove any workflow changes
      # and attempt to commit and push again. This is helpful because we will have a commit
      # with the correct prefix that we can then --amend with @npmcli/stafftools later.
      - name: Push All Changes Except Workflows
        if: steps.apply.outputs.changes && steps.push.outcome == 'failure'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git reset HEAD~
          git checkout HEAD -- .github/workflows/
          git clean -fd .github/workflows/
          git commit -am "${{ steps.apply.outputs.message }}"
          git push

      # Check if all the necessary template-oss changes were applied. Since we continued
      # on errors in one of the previous steps, this check will fail if our follow up
      # only applied a portion of the changes and we need to followup manually.
      #
      # Note that this used to run `lint` and `postlint` but that will fail this action
      # if we've also shipped any linting changes separate from template-oss. We do
      # linting in another action, so we want to fail this one only if there are
      # template-oss changes that could not be applied.
      - name: Check Changes
        if: steps.apply.outputs.changes
        run: |
          npm exec --offline ${{ steps.flags.outputs.workspace }} -- template-oss-check

      - name: Fail on Breaking Change
        if: steps.apply.outputs.changes && startsWith(steps.apply.outputs.message, 'feat!')
        run: |
          echo "This PR has a breaking change. Run 'npx -p @npmcli/stafftools gh template-oss-fix'"
          echo "for more information on how to fix this with a BREAKING CHANGE footer."
          exit 1
