Closed brianjmurrell closed 4 years ago
Another user recently mentioned this problem in an already closed issue (https://github.com/stefanzweifel/git-auto-commit-action/issues/71#issuecomment-660470689).
I didn't have the time yet to test it myself, but could you try creating a Personal Access Token (PAT) and use that token instead of the normal secrets.GITHUB_TOKEN
?
Will update the README accordingly when we've found the solution that works for everybody.
@brianjmurrell @stefanzweifel
Works fine with a personal access token!
👌
@localheinz Thanks for the update! Will rewrite the section about protected branches in the README soon.
How does a Personal Access Token work for teams/organisations where dozens of people work on the same repo?
@brianjmurrell I guess your question is: "How can I create a Personal Access Token for an org?"
That's currently not possible. I think this SO answer sums it up pretty good:
That's not possible currently, you can only create tokens for user accounts since user accounts have permissions associated with them (organizations don't). So, you'd need to create a token with an account which has access to the repository in question and give that to Travis. You can also create a machine account for that purpose.
https://stackoverflow.com/a/31160721/3863449
If you're in an org and don't want to create a PAT from your own personal accounts, the recommended way is to create a machine/bot account, and create a PAT from that machine account.
@brianjmurrell
As @stefanzweifel said: I have created @ergebnis-bot and use its personal access token in repositories I control.
Similarly, in other organizations we have also created bot accounts. Secrets can be easily shared using organization secrets.
Just a quick update: I've updated the README with a note on protected branches. In addition to the --force
-option which has to be passed to the Action, I've also added a note on the need of a PAT.
https://github.com/stefanzweifel/git-auto-commit-action#push-to-protected-branches
I'm closing this issue for now. If you think your issue is not resolved or have any other question, feel free to reopen or create a new issue.
It seems like opening quite a wide gate to allow force pushes to protected branches. We have that disabled specifically to prevent accidental pushes to master where a user meant to push to their own PR/branch. Is there no finer grained control over this than all-or-none?
@brianjmurrell It's definitely not the most beautiful solution for this problem, however, this Action just uses the git
-binary to do all the action.
As far as I know, there are no API endpoints which would accomplish the same which would make this whole "push to protected branch"-thing safer.
And I totally understand that your org has enabled protected branches and disabled the force-push option. (The feature exists for that reason 😄 )
However, if Actions would be excluded from these rules and Actions could push to protected branches, they could create the same havoc as a user would be able to 🤷
I have an issue, which I feel belongs to this discussion.
There is a "Commits of this Action do not trigger new Workflow runs" in the README, which states: The resulting commit will not trigger another GitHub Actions Workflow run.
. And according to the GitHub limitations, using a personal access token (PAT) changes this behaviour.
My goal is to create a workflow in an organization repository, which has a step that commits and pushes changes through this action. The branch is protected so I have do force push and to use a bot with PAT. But using PAT causes recursive workflow runs. Is there a way to fix this?
I guess my workflow could need rethinking, but if this is a common scenario (as it seems to me), then using this action with PAT will always cause recursive workflow runs.
@dimitarspassov Using this Action with a PAT shouldn't cause recursive workflows runs automatically. It all depends on what your workflow is changing.
For example, if your workflow is storing the current time and date in a text file (date > current-date.txt
), and you commit and push the file to the remote repository with a PAT, it will definitely cause endless recursive workflow runs.
If your workflow does something similar and everytime it runs would commit something, I think you should be able to prevent the endless workflows runs by using if conditions on the job. (Docs about if conditions)
The above example could look like this:
The workflow clones the repo, writes the current time in a txt-file and commits the changes pack to the repo by using a PAT. Howerver, the job itself is protected by a if-clause and will only run, if the user who started the workflow run is not org-bot
.
name: My Workflow
on: push
jobs:
my-workflow:
# ↓ This condition is important
if: github.actor != 'org-bot'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
token: ${{ secrets.PAT }}
ref: ${{ github.head_ref }}
# ...
run: date > current-date.txt
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: My Commit Message
branch: ${{ github.head_ref }}
commit_user_name: org-bot
But please note: I'm not 100% sure this actually works. I'm not sure if commit_user_name
and github.actor
are the same values or if you would have to use the actual GitHub username of your bot account here.
Thank you @stefanzweifel for the quick answer.
I've just finished testing and it seems that the if-conditions are the way to go here.
Unfortunately, I have a workflow job, that is required as part of the branch protection. Even with force pushes allowed and using the bot's PAT, I get an error:
remote: error: GH006: Protected branch update failed for refs/heads/master.
remote: error: Required status check "build-and-test" is expected.
I suppose what I'm trying to achieve may not be possible, but is there still a way to work this out?
@dimitarspassov By the name of the check ("build-and-test") I assume that a push could only happen if your project is successfully built and tested.
The Action would therefore have to be triggered when build-and-test
finishes. Maybe this can be achieved with the workflow_dispatch
-event.
However, this makes things just way too complicated.
@stefanzweifel Yep, I agree with your conclusion. I will have to reconsider the general approach. Thanks for the quick answer again!
@brianjmurrell It's definitely not the most beautiful solution for this problem, however, this Action just uses the
git
-binary to do all the action. As far as I know, there are no API endpoints which would accomplish the same which would make this whole "push to protected branch"-thing safer.And I totally understand that your org has enabled protected branches and disabled the force-push option. (The feature exists for that reason 😄 )
However, if Actions would be excluded from these rules and Actions could push to protected branches, they could create the same havoc as a user would be able to 🤷
We are using develop-on-master
workflow, so force pushing to master could clobber some actual commits.
@stefanzweifel could you please help me understand why force-pushes are necessary at all?
cc @opp-svega
@antonmos
could you please help me understand why force-pushes are necessary at all?
I assume that your master
branch is protected, right?
By default, nobody can push to a protected branch: Not you from your command line or any other actor (like git-auto-commit
in a GitHub Actions Workflow run).
To circumvent this and push through the branch protection, you can use git force pushes.
In your terminal you would use git push --force
, in git-auto-commit
you would use the push_options: '--force'
option. (Note that you need to allow force pushes to protected branches in your repo).
As mentioned before, git-auto-commit
is just a wrapper around the git
binary. So there is no other way to change a file in a workflow and push it to a protected without using force-pushes.
If you don't want to use force-pushes, and master
is your only protected branch, you would have to rewrite your workflow that uses git-auto-commit
so that it never runs on master
. For example it would only listen to the pull_request
-event and push your changes in a PR.
More on force pushes on protected branches:
By default, nobody can push to a protected branch: Not you from your command line or any other actor (like git-auto-commit in a GitHub Actions Workflow run)
I dont believe this is accurate. Protected branches have a setting for "Restrict who can push to matching branches" and "Include administrators" which are off by default. If they are off, then Administrators can push to a protected branch without meeting configured restrictions (e.g. PR reviews) (i just tested this). Note that this is different from force push
ing, which is disable for all protected branches unless Allow force pushes
is enabled (it's disabled by default).
My goal is to prevent force-pushing to master because it can break history/auditing/drop commits, but it is up to the individual to determine if PRs is need for a give change, i.e. there is no need to PR if you are fixing formatting in a README or if you are doing work in a pair. That said, all the actions should run regardless of whether the work is coming via PR or not.
So, if i am not mistaken, there is no need to force push if you are just trying to get an additive commit to a protected branch.
What is not clear to me is why we needed to specify push_options: '--force'
if git-auto-commit-action is only adding new commits, while i am able to push to protected master branch directly without using --force
@antonmos Agree. "Nobody" wasn't accurate. (I honestly haven't used protected branchens in a long while and wasn't aware that there was an "Include Administrators" option).
And I totally get what you want to achieve here. force-pushing is always a risky move.
What is not clear to me is why we needed to specify push_options: '--force' if git-auto-commit-action is only adding new commits, while i am able to push to protected master branch directly without using --force
When your Workflow is run, and the git-auto-commit Action is executed, the git push
call is not run in the name of the GitHub user antonmos
but rather as a "GitHub Actions system user". (See the docs about Authentication in a Workflow)
Let's imagine that your repository has protected branches setup like this:
Now you make a commit from you terminal and push it to master
. Because you are an administrator, it goes through.
Now a Workflow is triggered which will update/format README.md
. git-auto-commit
detects the change, creates a commit and tries to push it to GitHub.
It will fail with the following error message.
remote: error: GH006: Protected branch update failed for refs/heads/master.
remote: error: At least 1 approving review is required by reviewers with write access.
To https://github.com/stefanzweifel/repo
! [remote rejected] master -> master (protected branch hook declined)
error: failed to push some refs to 'https://github.com/stefanzweifel/repo'
Error: Invalid status code: 1
As the Workflow is run as the "GitHub Actions user" it's not detected as an administrator of the repo and the protected branches rules apply.
To circumvent this, you have to create a Personal Access Token. With this token, the git push
command will be executed in your name (as an administrator). the protected branches rules shouldn't apply then.
Does this clarify your questions? (Also feel free to submit a PR to the README/docs, if you think the part about protected branches can be made clearer)
The line about needing push_options: --force
might be out of date. I will do some testing over the next few days and update the README accordingly.
Thank you for your reply! We set it up with a PAT and made that user Admin in this repo and it worked without push_options: --force
Thank you @stefanzweifel.
Could you please clarify which scopes are needed for the Personal Access Token to work? The full list with descriptions is here: https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps
I'm guessing something like repo:status
but maybe full repo
is needed?
Additionally GitHub just released a "new version" of Personal Access Tokens - https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/ - do you think it's possible to use those instead? Will it work without any code change in the action?
Thanks in advance :)
edit: if you will be able to assist me understanding these i'd be happy to contribute - either to README to clarify or to code if some code change would be needed.
@zmilonas
Could you please clarify which scopes are needed for the Personal Access Token to work? The full list with descriptions is here: https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps I'm guessing something like repo:status but maybe full repo is needed?
Last time I checked, the token needs repo
and workflow
access. We've documented this in the README here:
If you create a personal access token, apply the repo and workflow scopes.
Additionally GitHub just released a "new version" of Personal Access Tokens - https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/ - do you think it's possible to use those instead? Will it work without any code change in the action?
I think that should work. From the announcement post I could see that the GraphQL API is not yet supported. git-auto-commit doesn't use any API directly. It just does a git push
. Authentication happens through actions/checkout
.
Regarding the scopes from the new fine grained PATs, I think you would need "Read and Wrtie" for "Actions" and "Contents". But I haven't tested this yet.
Feel free to give this all a try. If you think the docs in the README needs to be updated, feel free to create a pull request.
FYI, in order for this to work I had to do
if: github.event.head_commit.author.username != 'tag-bot'
github.actor
is always ... me :)
We may use GitHub Apps - Consistently allow GitHub Apps as exceptions to branch protection rules.
Authenticating as a GitHub App in a GitHub Actions workflow.
- name: Create Token
id: create_token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
token: ${{ steps.create_token.outputs.token }}
Version of the Action
v4.4.0
Describe the bug Not working with a protected branch despite the project enabling force-pushes.
Screenshots
Used Workflow https://github.com/daos-stack/pipeline-lib/blob/master/.github/workflows/update_pipeline_lib_branch.yml
The failed action: https://github.com/daos-stack/pipeline-lib/runs/900246701?check_suite_focus=true
I was able to push from the CLI: