Skip to content

Commit 3c4d926

Browse files
authored
Develop/1.0 (#190)
1 parent 6a21db9 commit 3c4d926

3 files changed

Lines changed: 64 additions & 20 deletions

File tree

.github/actions/github/branch-protection/lock/action.yml

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: 'Lock branch'
22
author: 'Pete Sramek'
3-
description: 'Apply branch protection to prevent direct pushes. Requires PRs with at least one approval.'
3+
description: 'Apply branch protection to prevent direct pushes. Requires PRs with configurable approval count; admins can optionally bypass all restrictions.'
44
inputs:
55
branch:
66
description: 'Branch name to lock.'
@@ -9,7 +9,19 @@ inputs:
99
description: 'GitHub token with administration:write (repo admin) permission. Use a PAT; GITHUB_TOKEN cannot call the branch protection API.'
1010
required: true
1111
lock-branch:
12-
description: 'When true, sets lock_branch to prevent even PR merges (use during automated operations). When false (default), only direct pushes are blocked; PRs with required reviews can still be merged.'
12+
description: 'When true, sets lock_branch to prevent even PR merges (use during automated operations). When false (default), only direct pushes are blocked; PRs can still be merged.'
13+
required: false
14+
default: 'false'
15+
required-approving-review-count:
16+
description: 'Number of approving reviews required before a PR can be merged. Set to 0 to require PRs without requiring approvals.'
17+
required: false
18+
default: '1'
19+
dismiss-stale-reviews:
20+
description: 'When true, approved reviews are dismissed when new commits are pushed to the branch.'
21+
required: false
22+
default: 'true'
23+
bypass-admins:
24+
description: 'When true, repository admins are exempt from all branch protection rules (enforce_admins is disabled). When false (default), admins are also subject to the rules.'
1325
required: false
1426
default: 'false'
1527

@@ -21,23 +33,31 @@ runs:
2133
env:
2234
GH_TOKEN: ${{ inputs.token }}
2335
run: |
24-
if ! gh api --method PUT /repos/${{ github.repository }}/branches/${{ inputs.branch }}/protection \
25-
--input - << 'EOF'
26-
{
27-
"required_status_checks": null,
28-
"enforce_admins": false,
29-
"required_pull_request_reviews": {
30-
"dismiss_stale_reviews": true,
31-
"require_code_owner_reviews": false,
32-
"required_approving_review_count": 1
33-
},
34-
"restrictions": null,
35-
"allow_force_pushes": false,
36-
"allow_deletions": false,
37-
"lock_branch": ${{ inputs.lock-branch }}
38-
}
39-
EOF
40-
then
36+
ENFORCE_ADMINS=true
37+
if [ '${{ inputs.bypass-admins }}' = 'true' ]; then
38+
ENFORCE_ADMINS=false
39+
fi
40+
41+
PAYLOAD=$(jq -n \
42+
--argjson review_count '${{ inputs.required-approving-review-count }}' \
43+
--argjson dismiss_stale '${{ inputs.dismiss-stale-reviews }}' \
44+
--argjson enforce_admins "$ENFORCE_ADMINS" \
45+
--argjson lock_branch '${{ inputs.lock-branch }}' \
46+
'{
47+
"required_status_checks": null,
48+
"enforce_admins": $enforce_admins,
49+
"required_pull_request_reviews": {
50+
"dismiss_stale_reviews": $dismiss_stale,
51+
"require_code_owner_reviews": false,
52+
"required_approving_review_count": $review_count
53+
},
54+
"restrictions": null,
55+
"allow_force_pushes": false,
56+
"allow_deletions": false,
57+
"lock_branch": $lock_branch
58+
}')
59+
60+
if ! echo "$PAYLOAD" | gh api --method PUT /repos/${{ github.repository }}/branches/${{ inputs.branch }}/protection --input -; then
4161
echo "::error::Failed to apply branch protection to '${{ inputs.branch }}'. Ensure the token has 'administration: write' permission and the branch exists."
4262
exit 1
4363
fi

.github/actions/github/branch-protection/unlock/action.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ inputs:
88
token:
99
description: 'GitHub token with administration:write (repo admin) permission. Use a PAT; GITHUB_TOKEN cannot call the branch protection API.'
1010
required: true
11+
fail-on-error:
12+
description: 'When true, the step fails if branch protection cannot be removed. When false (default), errors are silently ignored.'
13+
required: false
14+
default: 'false'
1115

1216
runs:
1317
using: composite
@@ -17,5 +21,9 @@ runs:
1721
env:
1822
GH_TOKEN: ${{ inputs.token }}
1923
run: |
20-
gh api --method DELETE /repos/${{ github.repository }}/branches/${{ inputs.branch }}/protection || true
24+
if [ '${{ inputs.fail-on-error }}' = 'true' ]; then
25+
gh api --method DELETE /repos/${{ github.repository }}/branches/${{ inputs.branch }}/protection
26+
else
27+
gh api --method DELETE /repos/${{ github.repository }}/branches/${{ inputs.branch }}/protection || true
28+
fi
2129
echo "🔓 Branch protection removed from '${{ inputs.branch }}'." >> $GITHUB_STEP_SUMMARY

.github/workflows/backtrack.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ jobs:
8787
token: ${{ secrets.GH_ADMIN_TOKEN }}
8888
lock-branch: 'true'
8989

90+
- name: 'Unlock preview branch for merge'
91+
if: ${{ steps.targets.outputs.preview-branch != '' }}
92+
uses: './.github/actions/github/branch-protection/lock'
93+
with:
94+
branch: ${{ steps.targets.outputs.preview-branch }}
95+
token: ${{ secrets.GH_ADMIN_TOKEN }}
96+
lock-branch: 'false'
97+
9098
- name: 'Backtrack: merge ${{ github.base_ref }} into ${{ steps.targets.outputs.preview-branch }}'
9199
if: ${{ steps.targets.outputs.preview-branch != '' }}
92100
env:
@@ -97,6 +105,14 @@ jobs:
97105
--field head="${{ github.base_ref }}" \
98106
--field commit_message="Backtrack: merge ${{ github.base_ref }} into ${{ steps.targets.outputs.preview-branch }}"
99107
108+
- name: 'Unlock develop branch for merge'
109+
if: ${{ steps.check-develop.outputs.exists == 'true' }}
110+
uses: './.github/actions/github/branch-protection/lock'
111+
with:
112+
branch: ${{ steps.targets.outputs.develop-branch }}
113+
token: ${{ secrets.GH_ADMIN_TOKEN }}
114+
lock-branch: 'false'
115+
100116
- name: 'Backtrack: merge ${{ steps.targets.outputs.merge-source }} into ${{ steps.targets.outputs.develop-branch }}'
101117
if: ${{ steps.check-develop.outputs.exists == 'true' }}
102118
env:

0 commit comments

Comments
 (0)