skip to Main Content

I have the following Github action on my repo. (For the sake of the example,) I want my workflow to add a git notes on the commit pushed (i.e. run git notes add -m "foo bar").

However, I get the following error:

fatal: update_ref failed for ref refs/notes/commits: cannot lock ref refs/notes/commits: Unable to create /home/runner/work/repo_name/repo_name/.git/refs/notes/commits.lock: Permission denied

What I’ve tried so far:

  • I thought using the ${{ github.token }} would help, but it isn’t.
  • I made sure to set “Read and Write permissions” in the repo’s Settings/Actions/General/Workflow permissions.
  • It is also not a chmod +x issue, as I’m running the command directly.
  • Setting the workflow permissions to write-all (as suggested by Azeem doesn’t solve it either.

Could this be a concurrency issue?


Github Action YAML file:

name: Notes

on:
  workflow_dispatch:

permissions: write-all

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
          token: ${{ github.token }}
      - name: Add git notes
        id: git-notes
        run: |
          git config user.name "Github Actions"
          git config user.email "[email protected]"
          git notes add -m "foo bar"
        env:
          GITHUB_TOKEN: ${{ github.token }}

Log:

 Run git config user.name "Github Actions"
  git config user.name "Github Actions"
  git config user.email "[email protected]"
  git notes add --allow-empty -m "foo bar"
  shell: /usr/bin/bash -e {0}
  env:
    GITHUB_TOKEN: ***
Removing note for object HEAD
fatal: update_ref failed for ref 'refs/notes/commits': cannot lock ref 'refs/notes/commits': Unable to create '/home/runner/work/marion_test_notes/marion_test_notes/.git/refs/notes/commits.lock': Permission denied
Error: Process completed with exit code 128.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to Azeem's minimal working example, I have troubleshot my issue.

    In my case, the error was generated because the commit had a note already (added by a separate step of the workflow).


    Building on Azeem's solution, I faced further issues that made the workflow fail, such as:

    • the commit has a note already (initial issue),
    • the note added is not “pushed upstream” — i.e. it disappears once the workflow ends, instead of being permanently added to the history,
    • other commits in the history have git notes already (but these are not synced by simply using the actions/checkout step),
    • the workflow fails if run a second time.

    Long story short, here is a workflow that robustly adds a git notes on the head checked out:

    name: git notes
    
    on:
      workflow_dispatch:
    
    jobs:
      add_git_note:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout repo
            uses: actions/checkout@v3
            with:
              fetch-depth: 0
              token: ${{ github.token }}
          - name: Add a git note
            run: |
              git fetch origin refs/notes/*:refs/notes/*
              git config user.name "github-actions"
              git config user.email "[email protected]"
              git notes add --allow-empty --force --message="foo bar"
              git notes show
              git push origin refs/notes/*
    

    Explanations:

    • git fetch origin refs/notes/*:refs/notes/*: “Pull” the git notes already existing in the repo (otherwise, it you'll get a conflict when trying to push your new note back upstream),
    • git config: Create git ID, which is required to add a note and push upstream,
    • git notes add: Add your note
      • --allow-empty: In case your message is empty (e.g. has been generated by a previous step of the workflow),
      • --force: In case you run the workflow again (so the commit has a note already). Note that (obviously), this overwrites any already existing git notes. You can otherwise have a look at git notes append.
    • git notes show: Cheap logging
    • git push origin refs/notes/*: Push the note back upstream (i.e. to the git repo), so that it survives the end of the workflow.

    References:


  2. Just tried to reproduce your scenario with this workflow:

    name: git_notes
    
    on:
      workflow_dispatch:
    
    permissions:
      actions: write
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v3
            with:
              fetch-depth: '0'
              token: ${{ github.token }}
          - name: Add git notes
            id: git-notes
            run: |
              git config user.name "Github Actions"
              git config user.email "[email protected]"
              git notes add -m "foo bar"
              git notes show
    

    But, it’s working fine.

    Here’s the workflow run (note is verified with git notes show):

    workflow run


    As the issue doesn’t seem to be with the workflow, you might to need check if there are any branch protection rules hindering this on your side.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search