update-git-submodules
🔁 update-git-submodules
Section titled “🔁 update-git-submodules”Update git submodule(s) to their latest commit or tag and emit structured outputs suitable for opening a pull request, driving a matrix job, or chaining further steps.
The action only updates the working tree — it does not commit or push. Combine it with a commit/PR step (e.g. peter-evans/create-pull-request) to ship the updates.
✨ Features
Section titled “✨ Features”- Two strategies —
commit(default) andtag - Filter which submodules to update
- Rich outputs:
json,matrix(drop-in forstrategy.matrix),prBody(markdown table) - Per-submodule outputs keyed by both submodule name and path
- Authenticates against private GitHub submodules via the
tokeninput - Optional
init: truemode clones submodules itself, so one PAT can cover both checkout and update for cross-repo private submodules
🚀 Usage
Section titled “🚀 Usage”example-update-git-submodules.yml
name: update-git-submodules exampleon: workflow_dispatch:jobs: example: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: stephansama/actions/update-git-submodules@v1 id: update - run: echo "${{ steps.update.outputs.prBody }}"🔐 Required permissions
Section titled “🔐 Required permissions”The calling workflow must grant the right token scope. Submodules must be present on disk before this step runs — either via actions/checkout with submodules: recursive, or by setting init: true here so this action clones them itself.
| Concern | What to do |
|---|---|
| Submodules in the same repo | The default ${{ github.token }} is enough. Set workflow permissions: contents: read. |
| Submodules in other public repos | The default token also works — no extra setup. |
| Submodules in other private repos | GITHUB_TOKEN is scoped to the current repo only. Either (a) pass a PAT (scope repo) / App installation token to both actions/checkout and this action’s token: input, or (b) skip submodules: recursive on checkout and use init: true here so this action clones them with the PAT itself. |
| Committing/pushing the update | Set permissions: contents: write on the caller’s workflow. This action itself does not commit. |
| Submodules present on disk | Either use actions/checkout@v4 with submodules: recursive (or true) before this step, or set init: true here and provide a token that can clone the submodules. |
Example wiring a PAT for cross-repo private submodules:
- uses: actions/checkout@v4 with: submodules: recursive token: ${{ secrets.SUBMODULE_PAT }}- uses: stephansama/actions/update-git-submodules@v1 with: token: ${{ secrets.SUBMODULE_PAT }}Or skip submodules: recursive on checkout and let this action handle cloning with init: true — one PAT covers both clone and update:
- uses: actions/checkout@v4 with: persist-credentials: false- uses: stephansama/actions/update-git-submodules@v1 with: init: true token: ${{ secrets.SUBMODULE_PAT }}📤 Outputs
Section titled “📤 Outputs”Static outputs
Section titled “Static outputs”| Name | Description |
|---|---|
json | JSON array of every update record |
matrix | { "include": [...] } — drop directly into strategy.matrix |
prBody | Markdown table summarizing all updates |
Dynamic per-submodule outputs
Section titled “Dynamic per-submodule outputs”For each updated submodule, the action emits two sets of identically-named keys — one prefixed by the submodule’s name and one prefixed by its path — so you can address it either way:
${name}--updated ${path}--updated${name}--path ${path}--path${name}--url ${path}--url${name}--remoteName ${path}--remoteName${name}--previousShortCommitSha ${path}--previousShortCommitSha${name}--previousCommitSha ${path}--previousCommitSha${name}--previousTag ${path}--previousTag${name}--previousCommitShaHasTag ${path}--previousCommitShaHasTag${name}--latestShortCommitSha ${path}--latestShortCommitSha${name}--latestCommitSha ${path}--latestCommitSha${name}--latestTag ${path}--latestTag (tag strategy only)${name}--prBody ${path}--prBody🧩 Inputs in detail
Section titled “🧩 Inputs in detail”gitmodulesPath— path to the.gitmodulesfile. Defaults to.gitmodules.init— whentrue, rungit submodule sync --recursivefollowed bygit submodule update --init --force --recursiveusing the configuredtokenbefore reading submodule state. Lets you omitsubmodules: recursiveonactions/checkoutand use a single PAT for both clone and update. Defaults tofalse.strategy—commit(default) walks each submodule to the tip of its tracked branch viagit submodule update --remote.tagresolves each submodule to its latest tag andgit reset --hards onto it.submodules— newline-delimited list of submodule names or paths to limit the update to. Empty (default) means all.token— GitHub token used to authenticate the underlyinggitoperations againstgithub.com. Defaults to${{ github.token }}.
Type Aliases
Section titled “Type Aliases”| Type Alias | Description |
|---|---|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
Functions
Section titled “Functions”| Function | Description |
|---|---|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |
|
|
‐ |