0

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 "bot@github.actions"
          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 "bot@github.actions"
  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.
ebosi
  • 1,285
  • 5
  • 17
  • 37
  • 1
    You're already configuring `token` so no need to set the env var `GITHUB_TOKEN`. Looks like it's a token permissions issue. See: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs. – Azeem Jan 23 '23 at 05:18
  • Thanks @Azeem for your suggestion! FYI, I added `permissions: write-all` to the workflow, but the error remains the same. – ebosi Jan 23 '23 at 10:23
  • 1
    Right. I'll try to reproduce it on my side and update you later. – Azeem Jan 23 '23 at 10:35

2 Answers2

1

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 "bot@github.actions"
          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.

Azeem
  • 11,148
  • 4
  • 27
  • 40
  • 1
    Thanks a lot, I do appreciate! I'll work from your workflow and see what makes mine fail. – ebosi Jan 23 '23 at 12:16
  • Thanks to your “minimal working example”, and after further troubleshooting, I've been able to devise a workflow that's robust enough for my use case. It's detailed in my answer below. – ebosi Jan 25 '23 at 09:51
1

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 "bot@github.com"
          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:

ebosi
  • 1,285
  • 5
  • 17
  • 37