I’m in this same boat here. Forced to choose between locking down my branch or automation. Frustrating.
+1 For having an option to allow GitHub actions to bypass branch protection.
I was able to create a workflow that temporarily disables the branch protection and then enables it again. This works fine if you don’t have multiple pull requests merged to master at the same time. And of course this means there is no branch protection for a few seconds.
The workflow
- Removes branch protection from
master
- Runs
npm version
to increment the release number and create a tag - Pushes the version number change to master and the tag
- Enables the branch protection for
master
again. - Builds and publishes the library to NPM
name: Publish Release
on:
push:
branches: [ master ]
jobs:
build-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup GIT
run: |
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
git config user.name "$GITHUB_ACTOR"
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 10
registry-url: https://npm.pkg.github.com/
scope: '@YOUR_ORG_HERE'
- name: Branch protection OFF
uses: octokit/request-action@v2.x
with:
route: PUT /repos/:repository/branches/master/protection
repository: ${{ github.repository }}
required_status_checks: |
null
enforce_admins: |
null
required_pull_request_reviews: |
null
restrictions: |
null
env:
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_REPO_ADMIN_CI_TOKEN }}
- name: Versioning
run: |
npm version minor -m "chore(release): %s"
git push "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY"
git push "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY" --tags
env:
NODE_AUTH_TOKEN: ${{secrets.GH_PACKAGES_TOKEN}}
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Branch protection ON
uses: octokit/request-action@v2.x
with:
route: PUT /repos/:repository/branches/master/protection
repository: ${{ github.repository }}
mediaType: |
previews:
- luke-cage
required_status_checks: |
strict: true
contexts:
- build
enforce_admins: |
null
required_pull_request_reviews: |
dismiss_stale_reviews: true
required_approving_review_count: 1
restrictions: |
null
env:
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_REPO_ADMIN_CI_TOKEN }}
- name: Build and Publish
run: |
npm ci
npm run build -- --prod
npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.GH_PACKAGES_TOKEN}}
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
It would be great if the github actions could bypass the branch protection policies for us, too. We would like to automatically add the latest changelog from LTS branches to the master branch’s changelog file on new LTS releases.
Plus one for asking this feature support
on:
push:
branches:
- master
jobs:
publish-gpr:
if: “!contains(github.event.head_commit.author.name, ‘GITHUBACTION’)”
runs-on: ubuntu-latest
steps:
…
- name: Set up git for commits
run: |
git config user.name “GITHUBACTION”
timeout-minutes: 1
- name: Push
run: git push --follow-tags --no-verify origin HEAD:master
timeout-minutes: 1
empty-job:
# if no jobs run, github action considers it a test failure – which seems like a bug
# this makes it so the top-level if statement for the job does not give status failure.
runs-on: ubuntu-latest
if: success()
steps:
- name: Meep
run: |
echo “This job will always succeed. If no jobs run, we still want the workflow to give status success.”
Am I right that these are the workaround options that we have?
-
Create an admin Personal Access Token, add to githubsecrets, and have the CI use that, and disable the “Include administrators” option under the protected branch setting
-
Not require approvals before merging to the protected branch
-
Have the CI create a PR which a human must manually approve and merge
Hey guys, we just spent a good time trying to work this out, posting our solution:
- Don’t enforce branch protection on admin.
- Create dedicated
system-admin
user and set him as admin on the protected repo. - Create a personal access token from
system-admin
user and store it asADMIN_TOKEN
in the repo secrets. - User
actions/checkout@v2
with the token we created. - Configure git name and email
Example:
jobs:
publish:
name: Publish
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
with:
token: ${{ secrets.ADMIN_TOKEN }}
- name: Configure CI Git User
run: |
git config --global user.name '@system-admin'
git config --global user.email 'system-admin@users.noreply.github.com'
- name: Do git actions
run: |
touch test.temp
git commit -am "Hey, I'm pushing from the CI! :)"
git push
Hey @nirsky do you know if you need a dedicated system-admin if you are part of on organization? I’m wondering if I can just have org matinees create an admin token? It doesn’t look like the username and email on your GitHub user actually means anything right?
Hey @renamari, you can definitely use the org maintainers token, no problem with that, the system-admin
was just an example.
The reason we created a dedicated user is because we use the same accounts for our personal GitHub, which means the token could be used to access our own personal repos…
Since you’re already providing the admin token, you might as well merge with the admin token. This would enable anyone to change the workflow as mentioned here.
Gitlab solves this by allowing secrets to be marked protected and only usable by protected branches.
Thank you! I was missing using personal access token for checkout step, happy you pointed it out
Seems like tying the perms on the action to the perms on the author of a commit could provide the automation power we want here without the security vulnerability. No?
Wow you saved me hours of debugging! ty!
So… there’s still no good way to do this without creating and managing a bot user just for this purpose, right?
It’s pretty absurd that Github still has no way to directly handle what should be a really straightforward, really common use case like this.
For Team and Enterprise plans, the “system-admin” user doesn’t necessarily need admin access:
"12. Optionally, if your repository is owned by an organization using GitHub Team or GitHub Enterprise Cloud, enable branch restrictions.
- Select Restrict who can push to matching branches .
- Search for and select the people, teams, or apps who will have permission to push to the protected branch."
- grant the “admin-user” push permissions
However, as an Owner (=full Admin) I cannot prevent myself from making stupid mistakes and am still able to push to a protected branch
This approach oddly doesn’t work for us. We already had a bot user for various GitHub activities and when we enforce the following:
… but add our non-admin bot user here:
We still get the following when attempting to merge into this protected branch:
git push origin stage
remote: error: GH006: Protected branch update failed for refs/heads/stage.
remote: error: At least 1 approving review is required by reviewers with write access.
We definitely clone the repository using the bot user’s token, too:
- name: Check Out Chart
id: chart_checkout
uses: actions/checkout@v2
with:
repository: ${{ env.HELM_CHART_REPO }}
token: ${{ secrets.BUILD_SERVICE_PAT }}
ref: master
path: ${{ github.workspace }}/${{ env.CHART_DIRECTORY }}
fetch-depth: 0
Anybody have any ideas why this feature is not working in this scenario? I am pretty puzzled and don’t really want to give our build robot admin controls.
Ugh, I’m trying to migrate away from Bitbucket, but this is just painful, almost to the extent I may have to stick with Bitbucket or pay a load of dollars for gitlab.
I seriously need the workflows to push to protected branches without having to use a PAT and then cause it to go around in a circle.
When we’re working on lots of small tickets we can just push/pr to our dev branch and let a workflow handle the merging into a QA branch which is then deployed for testing.
When features need testing we can PR into the QA branch so they get deployed for testing. If it’s not ready for our next release then its no big deal because it’s not in out dev branch.
I think I found at least a working solution to the problem, although a real solution by design would be beneficial.
First, you need to create a bot with a PAT. Give it sufficient permissions. For me this was only public_repo
. Then in the workflow that will do the push action, exclude the user (our bot is called nextcloud-cookbook-bot
). This can be achieved by a simple check on the complete workflow:
on:
push:
jobs:
deploy:
if: github.actor != 'nextcloud-cookbook-bot'
name: Deploy codebase
# ...
steps:
- ...
Then you can register a new remote in the git worker (replace USER
and TOKEN
with the login credentials for the bot and OWNER
and REPO
with the corresponding names of the repo):
git remote add NAME https://USER:TOKEN@github.com/OWNER/REPO.git
The current version of the actions/checkout
(v2 is used here) is setting an extraheader to authenticate with the GITHUB_TOKEN
when accessing the https interface. This will override the user/token given in the URL. So, for each push, you need to manually disable the GITHUB_TOKEN
via CLI options. See here:
git push -c "http.https://github.com/.extraheader=" NAME ...
With these changes I tried in a sandbox repo and it worked. The real repo is just set up today, so I have not checked if everything is working there yet but it should unless I did some serious bug here.
I have to admit I had a typo in this. The ordering seems important . Correct would be
git -c "http.https://github.com/.extraheader=" push NAME ...