I have a main.yml that calls other workflows via workflow_call
. The name of the workflows that are called are named workflow1
and workflow2
.
If workflow2
is called after workflow1
then workflow2
fails. If I switch them, then workflow1
fails.
Both workflows work okay when called via workflow_dispatch
.
Both workflows push to the repo.
The code I use for this is identical in both workflows:
- name: Commit and push the changes
run: |
echo "Initial status:"
git status
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add -A
echo "Status after git add:"
git status
git diff --cached --exit-code && exit 0 # Exit if no changes in the staging area
echo "Committing changes:"
git commit -m "chore: fetch content from various external sources"
echo "Pushing changes:"
git push
echo "Final status:"
git status
The second workflow fails with:
Run echo "Initial status:"
Initial status:
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: xxx.md
modified: yyy.md
modified: zzz.md
no changes added to commit (use "git add" and/or "git commit -a")
Status after git add:
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: xxx.md
modified: yyy.md
modified: zzz.md
diff --git a/xxx.md b/xxx.md etc etc
From what I understand is that if I have a main workflow that calls two other workflows, they all run on a separate “runner” so after workflow1
is executed, and workflow2
gets its own runner, a checkout of the repo should work?
I tried various suggestions made by AI:
1: Run this at the beginning of the git part (I don't understand why that would help, but I tried it):
git fetch origin main
git reset --hard origin/main
2: Run this at the beginning of the git part (I don't understand why that would help, but I tried it):
git pull origin main
I also tried a sleep of several seconds between the workflow1
and workflow2
but that didn't help.
What am I missing? I have spent a few hours on this now and I am not getting any further.
===
Addition: Below the caller yml script and the callee script(s), edited for simplicity, where you see “***”, those stars are a replacement for something that I decided to hide, same for “xxx”:
main.yml:
name: Import all and Deploy to GitHub Pages
on:
workflow_dispatch:
jobs:
workflow1:
uses: ./.github/workflows/workflow1.yml
secrets:
SECRET1: ${{ secrets.*** }}
SECRET2: ${{ secrets.*** }}
SECRET3: ${{ secrets.*** }}
workflow2:
needs: workflow1
uses: ./.github/workflows/workflow2.yml
secrets:
SECRET1: ${{ secrets.*** }}
SECRET2: ${{ secrets.*** }}
SECRET3: ${{ secrets.*** }}
workflow 1 (and workflow 2, they are basically the same):
# Summary: This GitHub Actions workflow fetches content from various external sources, updates a glossary, and deploys changes to GitHub Pages.
name: workflow1
on:
workflow_dispatch:
workflow_call:
secrets:
SECRET1:
required: true
SECRET2:
required: true
SECRET3:
required: true
jobs:
deploy:
name: Import external glossaries
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 19
cache: npm
- name: Install dependencies
run: npm ci
##############################
- name: Import external glossaries
env:
SECRET1: ${{ secrets.*** }}
SECRET2: ${{ secrets.*** }}
SECRET3: ${{ secrets.*** }}
run: sh xxx/xxx/xxx/main.sh
##############################
##############################
- name: Commit and push the changes
run: |
echo "Initial status:"
git status
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add -A
echo "Status after git add:"
git status
git diff --cached --exit-code && exit 0 # Exit if no changes in the staging area
echo "Committing changes:"
git commit -m "chore: fetch content from various external sources"
echo "Pushing changes:"
git push
echo "Final status:"
git status
##############################
I was able to reproduce this unintuitive behaviour and discovered two issues:
The parent workflow does not have permission to push to the repo and therefore the invoked workflows receive the same read-only permission as the parent workflow. Write permission needs to be explicitly given.
workflow2 is unable to push because the head of the underlying branch has progressed by the push of the workflow1. Even though workflow2 checks out the repo after workflow1 finishes it still gets the same branch head position as workflow1. Therefore, workflow2 has to pull the branch before making any changes.
The following shortened workflows work as expected:
Parent workflow:
name: workflow_main
on:
workflow_dispatch:
permissions:
contents: write
jobs:
workflow1:
uses: ./.github/workflows/workflow1.yaml
workflow2:
needs: workflow1
uses: ./.github/workflows/workflow2.yaml
Workflow2 (same as workflow1) - please see git pull:
name: workflow2
on:
workflow_dispatch:
workflow_call:
jobs:
deploy:
name: Import external glossaries
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Import external glossaries
run: |
git pull
echo $RANDOM > workflow2.txt
- name: Commit and push the changes
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "chore: fetch content from various external sources"
git push
git status