Skip to content

fix: Set explicit permissions in shared workflows (#42) #39

fix: Set explicit permissions in shared workflows (#42)

fix: Set explicit permissions in shared workflows (#42) #39

name: Sync Common Workflows
# Sync common workflows across repos. If a workflow template changes here,
# this will create a PR in each of our other repos to update the actual
# workflows. This is only done for workflows which are already installed with
# the same names as used here.
#
# The manual trigger can be used to create PRs for specific workflows and repos
# without regard for the workflow already being installed. This is useful for
# distributing workflows for the first time.
#
# The token used by this workflow (SHAKA_BOT_PR_TOKEN) is associated with the
# "shaka-bot" account, and must have at least "workflow" and "read:org"
# permissions.
on:
workflow_dispatch:
# Allows for manual triggering.
inputs:
repos:
type: string
description: A space-separated list of repos to push to.
workflows:
type: string
description: |
A space-separated list of workflows to push.
Pushes even if the workflow doesn't exist upstream.
push:
branches:
- main
paths:
- .github/workflows/sync-common-workflows.json
- sync-labels/sync-labels.yaml
- update-issues/update-issues.yaml
- validate-pr-title/validate-pr-title.yaml
env:
CONFIG: .github/workflows/sync-common-workflows.json
PR_BRANCH: sync-common-workflows
jobs:
sync-workflows:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: workflows
- name: Sync Workflows
run: |
git config --global user.email "[email protected]"
git config --global user.name "Shaka Bot"
echo "${{ secrets.SHAKA_BOT_PR_TOKEN }}" | gh auth login --with-token
REPO_LIST="${{ github.event.inputs.repos }}"
if [[ "$REPO_LIST" == "" ]]; then
REPO_LIST=$(cat workflows/$CONFIG | jq -r .repos[])
fi
WORKFLOW_LIST="${{ github.event.inputs.workflows }}"
SKIP_EXISTING=false
if [[ "$WORKFLOW_LIST" == "" ]]; then
WORKFLOW_LIST=$(cat workflows/$CONFIG | jq -r .workflows[])
SKIP_EXISTING=true
fi
for REPO in $REPO_LIST; do
# Fork each repo under shaka-bot if we haven't yet.
gh repo fork "$REPO" --clone=false
# Some messages from "gh repo fork" don't end in a newline.
# Add a newline to clean up the logs.
echo ""
# Pause between forking and cloning. This seems to fix errors that
# occur when trying to clone in one step or trying to fork and then
# immediately clone.
sleep 5
# Clone each forked repo.
FORK="shaka-bot/$(basename $REPO)"
git clone "https://${{ secrets.SHAKA_BOT_PR_TOKEN }}@github.com/$FORK"
# Use a subshell to change directories. The working directory will
# revert when the subshell ends, so each loop starts from the same
# place.
(
cd $(basename "$REPO")
# Add the upstream remote and update it.
git remote add upstream https://github.com/$REPO
git fetch upstream
# Create a local branch for a potential PR. Start at main.
git checkout -b "$PR_BRANCH" upstream/main
for WORKFLOW in $WORKFLOW_LIST; do
# Only update a workflow if that repo uses it, or if we're
# forced by a manual trigger.
if [[ "$SKIP_EXISTING" == "false" || -e ".github/workflows/$(basename $WORKFLOW)" ]]; then
cp ../workflows/$WORKFLOW .github/workflows/
git add ".github/workflows/$(basename $WORKFLOW)"
echo "Syncing $(basename $WORKFLOW) in $REPO"
else
echo "Skipping $(basename $WORKFLOW) in $REPO"
fi
done
# If anything has changed, generate a commit in a PR branch.
if ! git diff --cached --quiet; then
echo "chore: Sync common workflows" > .sync-pr-title
echo "This is an automated sync of common workflows for this organization." > .sync-pr-body
echo "The upstream source is:" >> .sync-pr-body
echo "https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" >> .sync-pr-body
(cat .sync-pr-title; echo; cat .sync-pr-body) > .sync-pr-message
git commit -F .sync-pr-message
git push -f origin "HEAD:$PR_BRANCH"
echo "Pushed to branch in $REPO"
# If there's not an open PR from that branch, create one.
PR_URL=$(gh pr list -H "$PR_BRANCH" --json url | jq -r first.url)
if [[ "$PR_URL" == "null" ]]; then
gh pr create \
--title "$(cat .sync-pr-title)" \
--body-file .sync-pr-body \
--head shaka-bot:$PR_BRANCH
echo "Created PR in $REPO"
else
gh pr edit "$PR_URL" --body-file .sync-pr-body
echo "Updated PR body in $REPO"
fi
else
echo "No changes in $REPO"
fi
)
done