submodules-update
The Workflow File​
name: CI - Update Submodules
on:
workflow_dispatch:
permissions:
contents: write # allows pushing commits/tags/branches
jobs:
update-submodules:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Update submodules to remote
run: git submodule update --init --remote
- name: Commit submodule updates
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Update submodules to latest remote" || echo "No changes to commit"
git push
With key​
Create new workflow file: (.github/workflows/update-submodules.yml)
name: Update Submodules
on:
workflow_dispatch: # Allows manual triggering
schedule:
- cron: "0 2 * * *" # Runs every day at 2:00 AM UTC (Optional)
permissions:
contents: write # allows pushing commits/tags/branches
jobs:
update-submodules:
runs-on: ubuntu-latest
steps:
- name: 1. Checkout Repository
# This action fetches the code into the workspace root (no extra folder needed).
uses: actions/checkout@v4
- name: 2. Configure SSH and Git (For PUSHING changes back)
run: |
# A. Identity Setup
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
# B. Key Creation (Same manual setup to enable git push)
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: 3. Execute Update and Push Script
# The commands now run from the root of the checked-out repository.
run: |
echo "Initialize submodules..."
# This must be run first on a fresh checkout
git submodule update --init
echo "Get version file.."
# Create or update the version file in the root
wget https://raw.githubusercontent.com/moodle/moodle/MOODLE_500_STABLE/version.php -O version.php
echo "Run: git submodule update --remote"
git submodule update --remote
# Check for changes
if [[ -n $(git status -s) ]]; then
echo "Changes detected. Committing..."
git add .
git commit -m "GitHub Actions submodule update."
# The SSH key allows this push
git push origin HEAD
else
echo "No changes detected. Skipping commit."
fi
Required Setup Steps​
To make this work, you cannot simply commit the file. You must configure the security credentials so GitHub Actions has permission to clone via SSH and push changes.
Generate a Deploy Key​
Run this in your local terminal (do not add a passphrase):
ssh-keygen -t ed25519 -C "github-actions" -f gh_deploy_key
Add the Public Key to the Repo​
cat gh_deploy_key.pub
- Copy the content of gh_deploy_key.pub.
- Go to the moodle500-plugins repository on GitHub.
- Navigate to Settings > Deploy keys.
- Click Add deploy key.
- Title:
GitHub Actions CI. - Important: Check the box Allow write access (otherwise the git push will fail).
- Paste the key and save.
Add the Private Key to Secrets​
cat gh_deploy_key
- Copy the content of the private key file gh_deploy_key.
- Go to the repository where this Action will run.
- Navigate to Settings > Secrets and variables > Actions.
- Click New repository secret.
- Name:
SSH_PRIVATE_KEY - Paste the private key content and save.
Markdown code for the status badge.​
Copy and paste this line at the very top of your README.md file:
[](https://github.com/AdrianoRuseler/moodle500-plugins/actions/workflows/update-submodules.yml)
Here is the step-by-step explanation of exactly what is happening in your workflow.​
The Triggers (on)​
on:
workflow_dispatch: # 1. Manual Trigger
schedule:
- cron: "0 2 * * *" # 2. Automatic Schedule
workflow_dispatch: Adds a "Run workflow" button in the GitHub Actions UI so you can test it anytime without waiting.schedule: Uses cron syntax to run the job automatically every day at 2:00 AM UTC.
The Setup Phase ("Configure SSH and Git")​
This step prepares the fresh, empty Linux runner (server) to act like your local computer.
# A. Identity Setup
git config --global user.email "github-actions[bot]..."
git config --global user.name "github-actions[bot]"
- Why: Git refuses to create a commit unless it knows who is committing. We use the standard GitHub bot identity here so the commits look "official."
# B. Key Creation
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
- The Magic: We take the text stored in your GitHub Repository Secrets and write it to a physical file on the server (id_ed25519).
chmod 600: This is critical. SSH requires private keys to be read-only by the owner. If permissions are too open (like 777), SSH will refuse to use the key for security reasons.
# C. Trusting GitHub
ssh-keyscan github.com >> ~/.ssh/known_hosts
- Why: When you SSH into a server for the first time, it usually asks: "The authenticity of host github.com can't be established. Are you sure?"
The Execution Phase​
# B. Update Logic
git submodule update --init
wget ... -O version.php
git submodule update --remote
update --init: If you added new submodules since the last run, this registers them locally.wget: Overwrites version.php with the latest raw file from Moodle HQ.update --remote: This is the heavy lifter. It goes into every submodule folder and pulls the latest commit from that submodule's remote branch (usually master or main).
The Conditional Push (Safety Mechanism)​
if [[ -n $(git status -s) ]]; then
echo "Changes detected. Committing..."
git add .
git commit -m "GitHub Actions submodule update."
git push origin HEAD
else
echo "No changes detected..."
fi
-
git status -s: This prints a short summary of changes. -
The Logic:
- If the output is not empty (-n), it means submodules were updated or version.php changed. We commit and push.
- If the output is empty, we do nothing.
-
Why: If we ran git commit when there were no changes, the Action would crash with an error ("nothing to commit"). This if block ensures the job always ends green (success).