There are two github repos: A & B. A will have B as its submodule.
https://github.com/org_name/A.git
https://github.com/org_name/B.git
A:
B@defad9 // a submodule in A
Here's the case, changes made in B and PR(#1) filed. Now I want run a build on A with the latest changes from B. Is there a github rest api can perform the update instead of git submodule update...?
I spent some time today figuring this out. First, get the commit hash of the parent repo:
GET /repos/:owner/:REPO_A/branches/master
$PARENT_SHA = {commit.sha}
You'll also need the commit from the submodule repo you want to update to:
GET /repos/:owner/:REPO_B/branches/master
$TARGET_SHA = {commit.sha}
Next, you'll create a git tree that updates the submodule reference:
POST /repos/:owner/:REPO_A/git/trees
{
"base_tree": $PARENT_SHA,
"tree": [
{
"path": "path/to/submodule",
"mode": "160000",
"type": "commit",
"sha": $TARGET_SHA
}
]
}
$TREE_SHA = {sha}
Now you can commit the tree:
POST /repos/:owner/:REPO_A/git/commits
{
"message": "Synchronize Handbook",
"tree": $TREE_SHA,
"parents": [$PARENT_SHA]
}
$COMMIT_SHA = {sha}
Finally, update master to point to your new commit:
PATCH /repos/:owner/:REPO_A/git/refs/heads/master
{
"sha": $COMMIT_SHA
}
I codified the GitHub calls described by Jason into a Transposit application that can be used as a GitHub webhook to auto-update a submodule sha in the parent repo whenever the submodule is updated.
Transposit hosts my javascript function and has a JavaScript API that I use to call GitHub's REST API. This function gets called by the webhook on commit to the submodule where it fetches the latest SHA for the submodule repository, updates the tree in the parent repo to the new sha, and commits it.
(params) => {
let owner = env.get('parentOwner');
let repo = env.get('parentRepo');
let branch = env.get('parentBranch');
let submoduleOwner = env.get('submoduleOwner');
let submoduleRepo = env.get('submoduleRepo');
let submoduleBranch = env.get('submoduleBranch');
let submodulePath = env.get('submodulePath');
let parentSha = api.run('github.get_branch_for_repo', {owner, repo, branch})[0].commit.sha;
let submoduleSha = api.run('github.get_branch_for_repo', {owner: submoduleOwner, repo: submoduleRepo, branch: submoduleBranch})[0].commit.sha;
let treeSha = api.run('github.create_git_tree', {
owner: owner,
repo: repo,
$body: {
"base_tree": parentSha,
"tree": [
{
"path": submodulePath,
"mode": "160000",
"type": "commit",
"sha": submoduleSha
}
]
}
})[0]
let commitSha = api.run('github.create_git_commit', {
owner: owner,
repo: repo,
$body: {
"message": `Auto-update submodule ${submoduleOwner}/${submoduleRepo} to ${submoduleSha}`,
"tree": treeSha.sha,
"parents": [parentSha]
}
})[0]
let editSha = api.run('github.edit_git_ref', {
owner: owner,
ref: `heads/${branch}`,
repo: repo,
$body: {
"sha": commitSha.sha
}
})
return editSha;
}
More information on how to use this webhook can be found here: https://www.transposit.com/blog/2019.08.23-github_submodule/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With