'Using GitHub Actions to automatically update the repo's submodules
Title says it all. I tried using a bunch of different git commands like git submodule update --remote --merge
and git submodule foreach git pull origin master
which work fine on my computer, but not when it's run on GitHub actions.
I tried adding git status
to the workflow and the status just shows "Up to date with origin/master, nothing to commit" or something like that.
Solution 1:[1]
If you need to auto update references to your submodules via GitHub actions:
Create a new workflow in your parent repository that will synchronize references:
name: 'Submodules Sync'
on:
# Allows you to run this workflow manually from the Actions tab or through HTTP API
workflow_dispatch:
jobs:
sync:
name: 'Submodules Sync'
runs-on: ubuntu-latest
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v2
with:
token: ${{ secrets.CI_TOKEN }}
submodules: true
# Update references
- name: Git Sumbodule Update
run: |
git pull --recurse-submodules
git submodule update --remote --recursive
- name: Commit update
run: |
git config --global user.name 'Git bot'
git config --global user.email '[email protected]'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git commit -am "Auto updated submodule references" && git push || echo "No changes to commit"
where
- CI_TOKEN is a security token variable in GitHub that have 'Read-Write' access to the parent repository, and 'Read' access to submodule repositories.
In the child (submodule) GitHub action notify the parent about changes.
name: 'Submodule Notify Parent'
on:
push:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
notify:
name: 'Submodule Notify Parent'
runs-on: ubuntu-latest
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
steps:
- name: Github REST API Call
env:
CI_TOKEN: ${{ secrets.CI_TOKEN }}
PARENT_REPO: <my_organization/my-app>
PARENT_BRANCH: develop
WORKFLOW_ID: <9999999>
run: |
curl -fL --retry 3 -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ env.CI_TOKEN }}" https://api.github.com/repos/${{ env.PARENT_REPO }}/actions/workflows/${{ env.WORKFLOW_ID }}/dispatches -d '{"ref":"${{ env.PARENT_BRANCH }}"}'
where
- PARENT_REPO - name of the parent repository as it is in Github (my_org/my_app or just my_app if there is no organization).
- WORKFLOW_ID - parent Wofklow ID to call via rest API. To find it run curl using your
CI_TOKEN
:curl -X GET -H "Authorization: token $CI_TOKEN" https://api.github.com/repos/$PARENT_REPO/actions/workflows
Repeat the workflow creation for every submodule.
P.S. For me it works very stable. Please add information about existing github actions with the above logic if there is any.
Solution 2:[2]
You can achieve this with a single action in the submodule repository:
name: Send submodule updates to parent repo
on:
push:
branches:
- main
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
repository: org/parent_repository
token: ${{ secrets.PRIVATE_TOKEN_GITHUB }}
- name: Pull & update submodules recursively
run: |
git submodule update --init --recursive
git submodule update --recursive --remote
- name: Commit
run: |
git config user.email "[email protected]"
git config user.name "GitHub Actions - update submodules"
git add --all
git commit -m "Update submodules" || echo "No changes to commit"
git push
You need to:
- adjust the name of the parent repository (here, I used
org/parent_repository
as an example). - create a private access token. with sufficient permissions to write in your parent repository and save it as a repository secret (under the name
PRIVATE_TOKEN_GITHUB
in my example above)
With this action, every push on the main
branch in the submodule repository will result in a commit pulling the update in the parent repository.
Solution 3:[3]
Simple solution
You pull and update the submodules recursively and then commit to the repo.
name: Update submodules
# Controls when the action will run.
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# This workflow contains a single job called "update"
update:
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Pull & update submodules recursively
run: |
git submodule update --init --recursive
git submodule update --recursive --remote
- name: Commit & push changes
run: |
git config --global user.name ${{ secrets.USER_NAME }}
git config --global user.email ${{ secrets.USER_EMAIL }}
git commit -am "Update submodules"
git push
Instead of using Github secrets like ${{ secrets.USER_NAME }}
I just hard code my git credentials since I'm lazy, but I figured you might care about security.
Solution 4:[4]
You can compare your GitHub Action source with one like submodule-branch-check
, which does make at least a git submodule update
.
Check if the update --remote
is enough to pull from its own remote origin.
Solution 5:[5]
it working for me, read acticle in here https://zenn.dev/ymmmtym/articles/dc741561759a49
name: Update submodules
on:
push:
branches:
- dev
pull_request:
branches:
- dev
jobs:
update_submodules:
name: Update submodules
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
token : ${{secrets.OOG_TOKEN}}
submodules : true
- name: Update submodules
id: update
run: git submodule update --remote --recursive
- name: Run git status
id: status
run: echo "::set-output name=status::$(git status -s)"
- name: Add and commit files
run: |
git add .
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git commit -m "Update submodules at $(date "+DATE: %Y-%m-%d TIME: %H:%M:%S")"
if: ${{ steps.status.outputs.status }}
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: dev
if: ${{ steps.status.outputs.status && github.event_name == 'push' }}
Solution 6:[6]
i try this it working for me
- uses: actions/checkout@v3
with:
repository: {owner}/repo
token: ${{ secrets.PRIVATE_TOKEN_GITHUB }}
submodules: recursive
- name: submodules recursively
run: git submodule update --init --recursive
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Droplet |
Solution 3 | Nermin |
Solution 4 | VonC |
Solution 5 | |
Solution 6 | Mansour Mehidi |