Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working on a protected branch #87

Closed
brianjmurrell opened this issue Jul 22, 2020 · 23 comments
Closed

Not working on a protected branch #87

brianjmurrell opened this issue Jul 22, 2020 · 23 comments
Labels
bug Something isn't working

Comments

@brianjmurrell
Copy link

brianjmurrell commented Jul 22, 2020

Version of the Action
v4.4.0

Describe the bug
Not working with a protected branch despite the project enabling force-pushes.

Screenshots
image

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:

$ git push origin HEAD:master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 380 bytes | 380.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:daos-stack/pipeline-lib.git
   a1bf9ea..fb2658d  HEAD -> master
@stefanzweifel
Copy link
Owner

stefanzweifel commented Jul 23, 2020

Another user recently mentioned this problem in an already closed issue (#71 (comment)).

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?

https://github.com/stefanzweifel/git-auto-commit-action#commits-of-this-action-do-not-trigger-new-workflow-runs

Will update the README accordingly when we've found the solution that works for everybody.

@stefanzweifel stefanzweifel added the bug Something isn't working label Jul 23, 2020
@localheinz
Copy link
Contributor

@brianjmurrell @stefanzweifel

Works fine with a personal access token!

👌

@stefanzweifel
Copy link
Owner

@localheinz Thanks for the update! Will rewrite the section about protected branches in the README soon.

@brianjmurrell
Copy link
Author

How does a Personal Access Token work for teams/organisations where dozens of people work on the same repo?

@stefanzweifel
Copy link
Owner

@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.

@localheinz
Copy link
Contributor

@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.

@stefanzweifel
Copy link
Owner

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.

@brianjmurrell
Copy link
Author

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?

@stefanzweifel
Copy link
Owner

@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 🤷

@dimitarspassov
Copy link

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.

@stefanzweifel
Copy link
Owner

@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.

@dimitarspassov
Copy link

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?

@stefanzweifel
Copy link
Owner

@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.

@dimitarspassov
Copy link

@stefanzweifel Yep, I agree with your conclusion. I will have to reconsider the general approach. Thanks for the quick answer again!

@antonmos
Copy link

@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

@stefanzweifel
Copy link
Owner

@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:

@antonmos
Copy link

antonmos commented Apr 19, 2021

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 pushing, 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

@stefanzweifel
Copy link
Owner

stefanzweifel commented Apr 20, 2021

@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:

Screenshot 2021-04-20 at 08 32 05

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.

@antonmos
Copy link

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

lmoureaux added a commit to lmoureaux/freeciv21 that referenced this issue Jun 25, 2022
Direct pushes to master are forbidden by branch protection rules. Have the
automation create a PR instead, so we can approve it and enable automerge. It's
a bit less convenient than a push but good enough for now. It also lets us
check that the action is working is intended. If this works well, we could
consider enabling automerge from within the action (or pushing directly as it
looks like it's supported via an access token [1]).

Closes longturn#955.

[1] stefanzweifel/git-auto-commit-action#87
lmoureaux added a commit to longturn/freeciv21 that referenced this issue Jun 25, 2022
Direct pushes to master are forbidden by branch protection rules. Have the
automation create a PR instead, so we can approve it and enable automerge. It's
a bit less convenient than a push but good enough for now. It also lets us
check that the action is working is intended. If this works well, we could
consider enabling automerge from within the action (or pushing directly as it
looks like it's supported via an access token [1]).

Closes #955.

[1] stefanzweifel/git-auto-commit-action#87
@zmilonas
Copy link

zmilonas commented Nov 2, 2022

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.

@stefanzweifel
Copy link
Owner

@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.

@bakayolo
Copy link

bakayolo commented Mar 6, 2023

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 :)

@air3ijai
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

8 participants