Skip to content

Commit

Permalink
Create PR in destination repo instead of pushing directly to main
Browse files Browse the repository at this point in the history
Previous version of the workflow assumed the workflow will be used to push the
updated docs directly to a branch that's synchronized with GitBook. But we
decided it will be safer to create a PR in the destination repo instead, that
will have the GitBook-synchronized branch set as a PR base branch.

Workflows that will use our reusable workflow will need to specify
`destinationBaseBranch` input (if not, `main` will be set as a default).

Objectives:
The destination repo may be in a bunch of different states when workflow is
executed, we wanted to handle those states. It is assumed that the reusable
worklow will be triggered if there's a `release` event in the project using this
workflow.

The release may not change anything in the contracts functions and comments
resulting in no changes between docs which are already in the destination repo
and those which got generated by the workflow. In that case we don't want to
push anything and create/update any PRs.

Probably the most common situation will be a case where a release modifies
something in contracts' functions/comments, resulting in a need for the docs
update. In such case we want to commit the changes and create a PR in the
destination repo. If there is already an earlier open PR updating the docs, we
want to update it instead of creating a new one.

To handle above objectives:
1. We configure `base_branch` and `head_branch` environment variables. The
   `base_branch` variable is set to value passed from `destinationBaseBranch`
   input. The `head_branch` will be set to `auto-update-solidity-api-docs`.
2. Next, we clone the `destinationRepo` and name it `dest-repo-clone` (we change
   the name because we want to avoid a situation where there's already a folder
   with the name of the destination repo present in repo where we run the
   workflow). All branches are cloned, and `head_branch` gets checked out.
3. We enter the cloned repo and checkout the `head_branch` (if it does not
   exist, we create a new branch under this name - based on `head_branch`- and
   checkout it).
4. If destination directory for docs does not exist, we create it. Then we
   synchronize the content of the `../generated-docs` folder with the content of
   destination folder.
5. Then we stage all the changes made in the `destinationRepo` and check if
   anything was staged. If nothing was staged, this means there were no changes
   to the dosc and we can finish the workflow without doing any changes to the
   destination repo (we end at step 5). If something was staged, we proceed to
   step 6.
6. We configure commiter in Git and commit the changes.
7. We push the commit to the `head_branch`.
8. Then we check if there's already an open PR existing for the `head_branch`. We
   do that by executing a curl command that lists all the open PRs in the
   `destinationRepo` that have the head branch set to `head_branch`. If no PRs
   match the criteria, the curl returns `[\n\n]`. If there's already a PR
   existing, then we're ok and we don't need to do anything else (PR got updated
   in step 7). If not, we create a PR using `hub` CLI tool
   (https://github.com/github/hub).
  • Loading branch information
michalinacienciala committed May 3, 2023
1 parent 283d7a7 commit 4d230f2
Showing 1 changed file with 48 additions and 24 deletions.
72 changes: 48 additions & 24 deletions .github/workflows/reusable-solidity-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ on:
type: string
required: false
default: "."
destinationBranch:
description: "A branch on the destination repository where the generated
Solidity docs will be pushed to (must exist)."
destinationBaseBranch:
description: "A branch on the destination repository which will be set
as a base branch of the PR updating Solidity docs (must exist)."
type: string
required: false
default: "main"
Expand Down Expand Up @@ -222,28 +222,52 @@ jobs:
git_user_signingkey: true
git_commit_gpgsign: true

- name: Sync generated docs with the specified repository
- name: Sync generated docs with the specified repository and create PR
if: inputs.publish == true
env:
API_TOKEN_GITHUB: ${{ secrets.githubToken }}
run: |
git config --global user.email ${{ inputs.userEmail }}
git config --global user.name ${{ inputs.userName }}
git clone --single-branch --branch ${{ inputs.destinationBranch }} \
https://x-access-token:[email protected]/${{ inputs.destinationRepo }}.git \
dest-repo-clone
cd dest-repo-clone
mkdir -p ${{ inputs.destinationFolder }}
rsync -avh ${{ inputs.rsyncDelete && '--delete' || '' }} \
../generated-docs \
${{ inputs.destinationFolder }}
git add -A
if git status | grep -q "Changes to be committed"
then
git commit ${{ inputs.verifyCommits && '-S' || '' }} -m "Update docs by https://github.com/${{ github.repository}}/actions/runs/${{ github.run_id}}"
echo "Pushing git commit"
git push --set-upstream origin HEAD:${{ inputs.destinationBranch }}
else
echo "No changes detected"
fi
echo "▶ Configure environment variables"
head_branch=auto-update-solidity-api-docs
base_branch=${{ inputs.destinationBaseBranch }}
echo "▶ Checkout destination repo"
git clone --branch $base_branch \
https://x-access-token:[email protected]/${{ inputs.destinationRepo }}.git \
dest-repo-clone
echo "▶ Create/checkout head branch"
cd dest-repo-clone
git checkout $head_branch || git checkout -b $head_branch
echo "▶ Synchronize docs"
mkdir -p ${{ inputs.destinationFolder }}
rsync -avh ${{ inputs.rsyncDelete && '--delete' || '' }} \
../generated-docs \
${{ inputs.destinationFolder }}
echo "▶ Commit changes"
git add -A
if git status | grep -q "Changes to be committed"
then
git config --global user.email ${{ inputs.userEmail }}
git config --global user.name ${{ inputs.userName }}
git commit ${{ inputs.verifyCommits && '-S' || '' }} \
-m "Update docs by https://github.com/${{ github.repository}}/actions/runs/${{ github.run_id}}"
echo "▶ Push commit"
git push --set-upstream origin HEAD:$head_branch
echo "▶ Check if PR for the head branch already exists"
dest_org=${${{ inputs.destinationRepo }}%%/*}
pr_for_head=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $API_TOKEN_GITHUB" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ inputs.destinationRepo }}/pulls?status=open&head=$dest_org:$head_branch")
if [[ $pr_for_head == $'[\n\n]' ]]; then
echo "▶ Checked. A PR for the head branch ($head_branch) will be created"
hub pull-request --base $base_branch \
--message "Update Solidity API docs" \
--message "Docs updated by workflow: https://github.com/${{ github.repository}}/actions/runs/${{ github.run_id}}"
else
echo "▶ Checked. A PR for head branch ($head_branch) already exists and got updated."
fi
else
echo "▶ No changes detected, no commits will be made."
exit 0
fi

0 comments on commit 4d230f2

Please sign in to comment.