gh-actions icon indicating copy to clipboard operation
gh-actions copied to clipboard

The action runs as the root user, causing subsequent workflows to fail

Open clear-ryan opened this issue 3 years ago • 11 comments

Describe the bug

Github Runners do not sufficiently clean up after themselves when there are file changes in the workspace, as this action does. This is specific to self-hosted runners.

What I'm seeing is:

Part 1

  • the workflow kicks off in a clean environment, fresh clone into a github workspace
  • there is a doc change needed and I've selected git-push: "true"
  • the file gets committed correctly, the workflow finishes successfully

Part 2

  • another workflow is kicked off in the same repo on the same runner, but the checkout action bails out do to the following error
    Error: error: insufficient permission for adding an object to repository database .git/objects
    Error: fatal: failed to write object
    Error: fatal: unpack-objects failed
    

It looks like this action writes files as the root or another privileged user while the github workflow initially runs as the self-hosted runner user (in my case runner). When this user updates files in the clone repo, it changes the permissions on them and then makes subsequent runs fail.

How can we reproduce it?

  1. self-hosted runner
  2. workflow that a. checkouts the repo b. runs this action with the git-push: "true" option on c. run the action again

Environment information

tf-docs action version: terraform-docs/[email protected]

      - name: Terraform Docs
        id: tfdoc
        env:
          GITHUB_TOKEN: ${{ github.token }}
        uses: terraform-docs/[email protected]
        with:
          config-file: .terraform-docs.yml
          git-commit-message: "[AUTO-COMMIT] Writing module ${{ matrix.modules }} README.md"
          git-push: "true"
          output-file: README.md
          working-dir: ${{ matrix.modules }}
        continue-on-error: true

clear-ryan avatar Jun 12 '21 16:06 clear-ryan

Thank you for reporting this, I'm gonna investigate. But in the meantime can you try running the same scenario on a runner by GitHub and not a self-hosted one? I'm wondering if this issue is universal or only limited to self-hosted runners.

khos2ow avatar Jun 13 '21 01:06 khos2ow

I can confirm that this issue also happens on Github-managed runners.

Run git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
  git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
  git config --local user.name "github-actions[bot]"
  git commit -m "Terraform docs update" -a
  shell: /usr/bin/bash -e {0}
error: insufficient permission for adding an object to repository database .git/objects
error: USAGE.md: failed to insert into database
error: unable to index file 'USAGE.md'
fatal: updating files failed
Error: Process completed with exit code 128.

I have to use a separate action to push otherwise the push from Terraform wouldn't trigger a new workflow since it isn't using the personal access token.

docs:
    name: Generate Module Docs
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
      with:
        ref: ${{ github.event.pull_request.head.ref }}
        persist-credentials: false

    - uses: satackey/[email protected]
      continue-on-error: true

    - name: Generate Module Docs
      uses: terraform-docs/[email protected]
      with:
        tf_docs_working_dir: .
        tf_docs_output_file: README.md
        tf_docs_output_method: inject
        tf_docs_git_push: 'false'
        tf_docs_find_dir: ./
        tf_docs_content_type: table

    - name: Commit files
      run: |
        git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
        git config --local user.name "github-actions[bot]"
        git commit -m "Terraform docs update" -a

    - name: Push changes
      uses: ad-m/github-push-action@65392840bda2e774394d5cd38ca33e5918aec2d3
      with:
        github_token: ${{ secrets.GH_ACTIONS_PAT }}
        branch: ${{ github.ref }}

guilhermef avatar Jun 29 '21 11:06 guilhermef

This can be fixed by setting the token on checkout e.g.

jobs:
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          ref: ${{ github.ref }}

      - uses: terraform-docs/[email protected]
        with:
          git-commit-message: 'docs: update readme'
          git-push: 'true'

abemedia avatar Aug 13 '21 16:08 abemedia

That's interesting, @clear-ryan @guilhermef would you be able to test the @abeMedia's suggestion?

khos2ow avatar Aug 13 '21 16:08 khos2ow

Hello @khos2ow, how are you?

I'm also having this problem, but for a different reason. I want to create a verified commit to push back to the PR, so I need an extra action. And, through my tests, specifying a specific PAT only enables you to trigger a new workflow run after a push from the action. That, however, does not fix the problem of insufficient permissions when trying to use further steps after creating the terraform documentation.

My action is created with the following logic:

  1. Checkout through Checkout V2 action
  2. Create TF Docs, but don't push - I need verified commits with GPG keys.
  3. Use Add & Commit action , to force push to git with GPG keys;

However, this always provides an error: Error: error: insufficient permission for adding an object to repository database .git/objects

I have a similar workflow, that uses the same steps:

  1. Checkout through Checkout V2 action
  2. Perform Terraform validations (init, validate, fmt) and commit the changes to GitHub;
  3. Use Add & Commit action , to force push to git with GPG keys;

With this, everything works as expected, without fail.

My current workflow code is as follows, while tf-startup job works fine, while tf-docs returns the error above.

name: Terraform Code Analysis

on:
  push:
    branches: [master, main, staging]
  pull_request:
    branches: [master, main, staging]
  workflow_dispatch:


jobs:
  tf-startup:
    name: Tf Setup (Init, Validate and fmt)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the code
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
          persist-credentials: true
          token: ${{ secrets.pat }}
          ref: ${{ github.event.pull_request.head.ref }}

      - name: terraform setup
        uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 1.0.5
      - name: terraform init
        id: init
        run: terraform init -backend=false
      - name: terraform validate
        id: validate
        run: terraform validate -no-color

      - name: Import GPG key
        id: import_gpg
        uses: crazy-max/ghaction-import-gpg@v2
        with:
          git_user_signingkey: true
          git_commit_gpgsign: true
        env:
          GPG_PRIVATE_KEY: ${{ secrets.key }}
          PASSPHRASE: ${{ secrets.pass }}

      - name: terraform fmt
        id: format
        run: terraform fmt -recursive

      - name: Add & Commit
        uses: EndBug/[email protected]
        if: github.event_name == 'pull_request'
        with:
          add: "."
          author_name: user123
          author_email: [email protected]
          message: "Terraform fmt executed"
          push: true


  tf-docs:
    name: Create Tf docs for modules
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the code
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
          persist-credentials: true
          token: ${{ secrets.pat }}
          ref: ${{ github.event.pull_request.head.ref }}

      - name: Render terraform docs inside the USAGE.md and push changes back to PR branch
        uses: terraform-docs/[email protected]
        with:
          find-dir: ./modules/
          output-method: replace
          # Do not push, so we can use GPG keys with the next action
          git-push: false
          template: |-
            <!--- BEGIN_TF_DOCS --->
            <!--- END_TF_DOCS --->

      - name: Import GPG key
        id: import_gpg
        uses: crazy-max/ghaction-import-gpg@v2
        with:
          git_user_signingkey: true
          git_commit_gpgsign: true
        env:
          GPG_PRIVATE_KEY: ${{ secrets.key }}
          PASSPHRASE: ${{ secrets.pass}}

      - name: Add & Commit
        uses: EndBug/[email protected]
        if: github.event_name == 'pull_request'
        with:
          add: "./modules/"
          author_name: user123
          author_email: [email protected]
          message: "Terraform docs created"
          push: true

Is there a way to create signed commits with this action?

dgteixeira avatar Sep 17 '21 17:09 dgteixeira

Hello @khos2ow, you had any chance to look at what I commented here earlier? Thanks!

dgteixeira avatar Dec 22 '21 10:12 dgteixeira

Hello,

Any update?

pfilourenco avatar Apr 26 '22 11:04 pfilourenco

Did the suggestion from @abemedia work for anyone?

sjgupta19 avatar Jul 15 '22 20:07 sjgupta19

The suggestion from @abemedia does work, but only if you just need to push the changes. I have a workflow where I run Prettier before publishing the files, which hits this issue as well.

btkostner avatar Jul 18 '22 21:07 btkostner

This is how I temporarily work around this issue until this action gets a permanent fix.

The problem only seems to occur on small new repos, where not all the objects folder exist yet on initial checkout.

https://github.com/terraform-docs/gh-actions/issues/90#issuecomment-1231312948

marcofranssen avatar Aug 30 '22 08:08 marcofranssen

This can be fixed by setting the token on checkout e.g.

jobs:
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          ref: ${{ github.ref }}

      - uses: terraform-docs/[email protected]
        with:
          git-commit-message: 'docs: update readme'
          git-push: 'true'

this works for me!

markti avatar Jul 26 '23 14:07 markti