| 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 }} |