How To Automatically update git submodules using GitHub Actions
Monorepo project structures with git submodules are great and easy to manage to benefit from a centralized data flow, and I personally use them for blog writing.
As an example, I’ll walk you around on how to setup a codebase to sync between two repositories, the website repo and the writings repo that holds markdown files, in my case, using the Github Actions CI/CD.
We’ll start by initializing the git submodule in my local website blog repo using:
git submodule add <https://github.com/0xWerz/writings> # <repo_you_want_to_sync_with>
This should create the repo directory.
Now on the writings repo we should create a webhook event that gets triggered each time a new push event happen to send a dispatch event to the website repo, using peter-evans/repository-dispatch@v3 to update its submodule(s)
In .github/workflows/dispatch_update.yml
name: Dispatch Update Submodule
on:
push:
branches:
- main
jobs:
dispatch:
runs-on: ubuntu-latest
steps:
- name: Dispatch update to Git Blog Project
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.PAT }}
repository: 0xWerz/werz
event-type: update-submodule
This should sent a update-submodule event to the 0xWerz/werz website repo. If the repositories are private you’d need a Personal Access Token (PAT) with the the contents: write permissions.
To listen to the events sents to the website (werz) repo, we should sent up a github action workflow as well. .github/workflows/update_submodule.yml
name: Update Submodule
on:
repository_dispatch:
types:
- update-submodule
jobs:
update-submodule:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT }}
submodules: recursive
- name: Authorize Git
run: |
git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
git config --global user.name "$GITHUB_ACTOR"
- name: Update submodule
run: |
git submodule update --init --recursive --remote -f
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
- name: Commit changes
run: |
git add writings
git commit -m "Update submodule to latest commit"
git push origin main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
This should be syncing each new push with the submodule.