stefanzweifel / git-auto-commit-action

Automatically commit and push changed files back to GitHub with this GitHub Action for the 80% use case.
MIT License
2k stars 228 forks source link

Refusing to allow a GitHub App to create or update workflow `.github/workflows/main.yml` without `workflows` permission #322

Closed atodorov closed 3 months ago

atodorov commented 7 months ago

git-auto-commit Version

v5

Machine Type

Ubuntu (eg. ubuntu-latest)

Bug description

I have configured permission: write-all and still get a failure because part of the commit is modifying GitHub actions files.

Steps to reproduce

https://github.com/kiwitcms/gitops/actions/runs/8056214742/job/22004837145?pr=5

Tried solutions

No response

Example Workflow

---
# MegaLinter GitHub Action configuration file
# More info at https://megalinter.io
name: MegaLinter

on:
  pull_request:

permissions: read-all

env: # Comment env block if you do not want to apply fixes
  # Apply linter fixes configuration
  APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool)
  APPLY_FIXES_EVENT: pull_request # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all)
  APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request)

concurrency:
  group: ${{ github.ref }}-${{ github.workflow }}
  cancel-in-progress: true

jobs:
  build:
    name: MegaLinter
    runs-on: ubuntu-latest
    # checkov:skip=CKV2_GHA_1:We need this for auto-commit
    permissions: write-all
    steps:
      # Git Checkout
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
          fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances

      # MegaLinter
      - name: MegaLinter
        id: ml
        # You can override MegaLinter flavor used to have faster performances
        # More info at https://megalinter.io/latest/flavors/
        uses: oxsecurity/megalinter/flavors/python@v7.9.0
        env:
          # All available variables are described at https://megalinter.io/latest/configuration/
          # and configured in .mega-linter.yml
          VALIDATE_ALL_CODEBASE: true
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # Upload MegaLinter artifacts
      - name: Archive production artifacts
        if: success() || failure()
        uses: actions/upload-artifact@v4
        with:
          name: MegaLinter reports
          path: |
            megalinter-reports
            mega-linter.log

      - name: git diff
        if: steps.ml.outputs.has_updated_sources == 1
        run: |
          git diff

      # Create pull request if applicable (for now works only on PR from same repository, not from forks)
      - name: Create Pull Request with applied fixes
        id: cpr
        if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
        uses: peter-evans/create-pull-request@v6
        with:
          token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
          commit-message: "[MegaLinter] Apply linters automatic fixes"
          title: "[MegaLinter] Apply linters automatic fixes"
          labels: bot
      - name: Create PR output
        if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
        run: |
          echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
          echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"

      # Push new commit if applicable (for now works only on PR from same repository, not from forks)
      - name: Prepare commit
        if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/dev' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
        run: sudo chown -Rc $UID .git/
      - name: Commit and push applied linter fixes
        if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/dev' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
        uses: stefanzweifel/git-auto-commit-action@v5
        with:
          branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}
          commit_message: "[MegaLinter] Apply linters fixes"

extracted from https://github.com/kiwitcms/gitops/pull/5/files


### Relevant log output

```shell
Started: bash /home/runner/work/_actions/stefanzweifel/git-auto-commit-action/v5/entrypoint.sh
INPUT_REPOSITORY value: .
INPUT_STATUS_OPTIONS: 
INPUT_FILE_PATTERN: .
INPUT_BRANCH value: mega-linter
Previous HEAD position was f700ab4 Merge ccdda2820d0941feb71b8dd42dc1eee4343fde8f into 52823bb1292ddbf305d26210c260139c1bd19331
Switched to a new branch 'mega-linter'
M   .github/workflows/main.yml
M   .github/workflows/pr.yml
M   action.yml
M   entrypoint.sh
branch 'mega-linter' set up to track 'origin/mega-linter'.
INPUT_ADD_OPTIONS: 
INPUT_FILE_PATTERN: .
INPUT_COMMIT_OPTIONS: 
INPUT_COMMIT_USER_NAME: github-actions[bot]
INPUT_COMMIT_USER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
INPUT_COMMIT_MESSAGE: [MegaLinter] Apply linters fixes
INPUT_COMMIT_AUTHOR: atodorov <atodorov@users.noreply.github.com>
[mega-linter 633ac82] [MegaLinter] Apply linters fixes
 Author: atodorov <atodorov@users.noreply.github.com>
 20 files changed, 471 insertions(+), 13 deletions(-)
 create mode 100644 megalinter-reports/IDE-config.txt
 create mode 100644 megalinter-reports/IDE-config/.checkov.yml
 create mode 100644 megalinter-reports/IDE-config/.gitleaks.toml
 create mode 100644 megalinter-reports/IDE-config/.grype.yaml
 create mode 100644 megalinter-reports/IDE-config/.hadolint.yaml
 create mode 100644 megalinter-reports/IDE-config/.idea/externalDependencies.xml
 create mode 100644 megalinter-reports/IDE-config/.jscpd.json
 create mode 100644 megalinter-reports/IDE-config/.markdown-link-check.json
 create mode 100644 megalinter-reports/IDE-config/.markdownlint.json
 create mode 100644 megalinter-reports/IDE-config/.secretlintrc.json
 create mode 100644 megalinter-reports/IDE-config/.vscode/extensions.json
 create mode 100644 megalinter-reports/IDE-config/.yamllint.yml
 create mode 100644 megalinter-reports/updated_sources/.github/workflows/main.yml
 create mode 100644 megalinter-reports/updated_sources/.github/workflows/pr.yml
 create mode 100644 megalinter-reports/updated_sources/action.yml
 create mode 100755 megalinter-reports/updated_sources/entrypoint.sh
INPUT_TAGGING_MESSAGE: 
No tagging message supplied. No tag will be added.
INPUT_PUSH_OPTIONS: 
To https://github.com/kiwitcms/gitops
 ! [remote rejected] HEAD -> mega-linter (refusing to allow a GitHub App to create or update workflow `.github/workflows/main.yml` without `workflows` permission)
error: failed to push some refs to 'https://github.com/kiwitcms/gitops'
Error: Invalid status code: 1
    at ChildProcess.<anonymous> (/home/runner/work/_actions/stefanzweifel/git-auto-commit-action/v5/index.js:17:19)
    at ChildProcess.emit (node:events:514:28)
    at maybeClose (node:internal/child_process:1105:16)
    at ChildProcess._handle.onexit (node:internal/child_process:305:5) {
  code: 1
}
Error: Invalid status code: 1
    at ChildProcess.<anonymous> (/home/runner/work/_actions/stefanzweifel/git-auto-commit-action/v5/index.js:17:19)
    at ChildProcess.emit (node:events:514:28)
    at maybeClose (node:internal/child_process:1105:16)
    at ChildProcess._handle.onexit (node:internal/child_process:305:5)
stefanzweifel commented 7 months ago

Hi @atodorov,

As far as I know, the default token used by GitHub Actions can't have workflows: write permission. Probably another security measure by GitHub, to prevent bad actions from stealing secrets from your repository.

(I can't find documentation about this, but I ran into a similar issues years ago)

The easiest solution might be to create a personal access token (PAT) and add it to your workflow. https://github.com/stefanzweifel/git-auto-commit-action?tab=readme-ov-file#commits-made-by-this-action-do-not-trigger-new-workflow-runs

Will add a warning to the README to warn users, that the action can't modify workflow files.

atodorov commented 7 months ago

(I can't find documentation about this, but I ran into a similar issues years ago)

Sadly I wasn't able to find documentation either and trying to set

permissions:
   workflows: write

is invalid syntax.

stefanzweifel commented 7 months ago

I also assume that the error message "refusing to allow a GitHub App to create or update workflow .github/workflows/main.yml without workflows permission" is just a UX error.

GitHub probably assumes that the push comes from a GitHub App, but GitHub Actions is not the same as a GitHub App. Maybe we can forward this to a feedback repo somewhere. 🤔

atodorov commented 7 months ago

GitHub probably assumes that the push comes from a GitHub App, but GitHub Actions is not the same as a GitHub App.

FTR I think in this case GitHub is correct. My commit (after I excluded the conflicting files) looks like this:

atodorov authored and github-actions[bot] committed

Where https://github.com/apps/github-actions redirects to https://github.com/features/actions. Internally github-actions is just another app for which you are automatically authenticated!

stefanzweifel commented 7 months ago

@atodorov This seems like a reasonable explanation. 👍

Back to your original issue, have you tried the approach with a personal access token? I'm fairly certain that this will resolve your issue. Can try to reproduce this on my end in the coming days/weeks.

blakeNaccarato commented 6 months ago

See https://github.com/stefanzweifel/git-auto-commit-action/issues/266#issuecomment-1859556587 for detail on creating and scoping a PAT for this.

Also https://github.com/stefanzweifel/git-auto-commit-action/issues/87#issuecomment-1939138661 for the nuclear option. They discuss setting up your own GitHub App to reliably commit to protected branches, but this "create an entire app and jump through lots of auth hurdles" approach would also apply to permitting a bot to do workflow editing. Maybe only worth it at scale across repos in a GitHub Org where PATs are forbidden.

stefanzweifel commented 3 months ago

I've updated the troubleshoot section in the README with a section that discussions this problem. We suggest using a PAT or the nuclear option of creating a GitHub app.