name: Manage Trunk Restrictions

permissions: {}

concurrency:
  group: manage-trunk-restrictions
  cancel-in-progress: false

on:
  workflow_dispatch:
    inputs:
      restrict:
        description: 'Restrict trunk branch'
        required: true
        type: boolean
  workflow_call:
    inputs:
      restrict:
        description: 'Restrict trunk branch'
        required: true
        type: boolean
      message:
        description: 'Slack message override (optional)'
        required: false
        type: string
        default: ''
      skip_approval:
        description: 'Skip the approval step (used for automatic failure recovery)'
        required: false
        type: boolean
        default: false
    secrets:
      SELENIUM_CI_TOKEN:
        required: true
      SLACK_WEBHOOK_URL:
        required: true

jobs:
  get-approval:
    name: Get Approval
    if: ${{ !inputs.skip_approval && (inputs.restrict || github.event_name == 'workflow_dispatch') }}
    uses: ./.github/workflows/get-approval.yml
    with:
      title: ${{ inputs.restrict && 'Trunk branch locking' || 'Trunk branch unlocking' }}
      message: ${{ inputs.restrict && 'Approval is required to begin release process.' || 'Approval is required to unlock trunk.' }}
    secrets:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  manage-trunk:
    name: Manage Trunk Branch
    needs: [get-approval]
    runs-on: ubuntu-latest
    if: always() && (needs.get-approval.result == 'success' || inputs.skip_approval || (!inputs.restrict && github.event_name != 'workflow_dispatch'))
    env:
      GH_TOKEN: ${{ secrets.SELENIUM_CI_TOKEN }}
      GH_REPO: ${{ github.repository }}
    steps:
      - name: Checkout ruleset definitions
        uses: actions/checkout@v6
        with:
          sparse-checkout: .github/rulesets
          sparse-checkout-cone-mode: false
      - name: Create release rulesets
        if: inputs.restrict
        shell: bash
        run: |
          set -euo pipefail
          existing=$(gh api "repos/$GH_REPO/rulesets")
          for f in .github/rulesets/release-*.json; do
            name=$(jq -r .name "$f")
            if jq -e --arg n "$name" 'any(.[]; .name == $n)' <<<"$existing" >/dev/null; then
              echo "Ruleset '$name' already exists; skipping"
            else
              echo "Creating ruleset: $name"
              gh api -X POST "repos/$GH_REPO/rulesets" --input "$f"
            fi
          done
      - name: Delete release rulesets
        if: ${{ !inputs.restrict }}
        shell: bash
        run: |
          set -euo pipefail
          existing=$(gh api "repos/$GH_REPO/rulesets")
          for f in .github/rulesets/release-*.json; do
            name=$(jq -r .name "$f")
            while IFS= read -r id; do
              echo "Deleting $name (id=$id)"
              gh api -X DELETE "repos/$GH_REPO/rulesets/$id"
            done < <(jq -r --arg n "$name" '.[] | select(.name==$n) | .id' <<<"$existing")
          done

  notify:
    name: Send Notification
    needs: [manage-trunk]
    if: always() && needs.manage-trunk.result == 'success'
    runs-on: ubuntu-latest
    steps:
      - name: Slack Notification
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_ICON_EMOJI: ${{ inputs.restrict && ':lock:' || ':unlock:' }}
          SLACK_COLOR: ${{ inputs.restrict && 'danger' || 'good' }}
          SLACK_CHANNEL: selenium-tlc
          SLACK_USERNAME: GitHub Workflows
          SLACK_TITLE: ${{ inputs.restrict && 'Trunk locked' || 'Trunk unlocked' }}
          SLACK_MESSAGE: ${{ inputs.message != '' && inputs.message || (inputs.restrict && 'Trunk has been locked.' || 'Trunk has been unlocked.') }}
          MSG_MINIMAL: actions url
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
