Transfer issues #44
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Transfer issues | |
# To run this action. | |
# 1. Create a personal access token (Classic) with the `repo` and `read:org` scopes.defaults: | |
# 2. Create a secret in the repository with whatever name you want, and paste the token as the value. | |
# 3. Run the action with the secret name as the `secret_name` input. | |
# | |
# Ex: gh secret set MY_TOKEN --body "<token_value>" && gh workflow run 90730614 --field count="10" --field from_name="addons-server" --field secret_name="MY_TOKEN" | |
# | |
# Note: you need to paste the PAT in body, so make sure to keep track of the value before saving it. | |
# Also verify the workflow ID is correct. You can run without arguments and select interactively. | |
# | |
# Note: After each run this action purges the secret from the repo action secrets. | |
# This prevents pollution or conflict. So you have to reset it every time. | |
on: | |
workflow_dispatch: | |
inputs: | |
count: | |
description: How many issues to transfer | |
default: "1" | |
required: true | |
from_name: | |
description: "the name of the mozilla/<from_name repository to transfer issues from" | |
required: true | |
secret_name: | |
description: "the name of the secret containing the PAT for the repository to transfer issues to" | |
required: true | |
permissions: write-all | |
env: | |
ALLOWED_REPOS: "addons-server,addons-frontend" | |
concurrency: | |
group: transfer | |
cancel-in-progress: true | |
jobs: | |
fetch_issues: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Transfer issues | |
env: | |
GH_TOKEN: ${{ secrets[format('{0}', inputs.secret_name)] }} | |
shell: bash | |
run: | | |
set -x | |
echo "token: $GH_TOKEN" | |
gh auth status | |
from_name="${{ inputs.from_name }}" | |
repo_label="repository:$from_name" | |
allowed_repos="${{ env.ALLOWED_REPOS }}" | |
repository_owner="${{ github.repository_owner }}" | |
to_name="${{ github.event.repository.name }}" | |
count="${{ inputs.count }}" | |
if [[ ! "$allowed_repos" =~ (^|,)"$from_name"(,|$) ]]; then | |
echo "Invalid from_name "$from_name". Exiting..." | |
exit 1 | |
fi | |
echo "Transferring issues from \"$repository_owner/$from_name\" to \"$repository_owner/$to_name\"" | |
repository_id=$(gh repo view "$repository_owner/$to_name" --json id --jq '.id') | |
issues_query=""" | |
query { | |
repository(owner: \"$repository_owner\", name: \"$from_name\") { | |
issues(first: $count, orderBy: {field: CREATED_AT, direction: ASC}) { | |
nodes { | |
id | |
} | |
} | |
} | |
} | |
""" | |
issues=$(gh api graphql -f query="$issues_query" --jq '.data.repository.issues.nodes[].id') | |
transfer_mutation="mutation {" | |
new_issues_counter=1 | |
while IFS= read -r issue_id; do | |
transfer_mutation+=" t${new_issues_counter}: transferIssue(input: { issueId: \"${issue_id}\", repositoryId: \"${repository_id}\", createLabelsIfMissing: true }) { issue { id url } }" | |
new_issues_counter=$((new_issues_counter+1)) | |
done <<< "$issues" | |
transfer_mutation+=" }" | |
new_issues=$(gh api graphql -f query="$transfer_mutation" --jq '.data | keys[] as $k | {url: .[$k].issue.url, id: .[$k].issue.id}') | |
new_issue_ids=$(echo "$new_issues" | jq -r '.id') | |
gh label create \"$repo_label\" -R "$repository_owner/$to_name" --force | |
label_id=$(gh api /repos/$repository_owner/$to_name/labels/$repo_label --jq '.node_id') | |
label_mutation="mutation {" | |
label_counter=1 | |
while IFS= read -r id; do | |
label_mutation+=" l${label_counter}: updateIssue(input: {id: \"$id\", labelIds: [\"$label_id\"]}) { __typename }" | |
label_counter=$((label_counter+1)) | |
done <<< "$new_issue_ids" | |
label_mutation+=" }" | |
gh api graphql -f query="$label_mutation" | |
echo "$new_issues" | jq -r '.url' | |
- name: Delete secret | |
if: always() | |
shell: bash | |
env: | |
GH_TOKEN: ${{ secrets[format('{0}', inputs.secret_name)] }} | |
run: | | |
set -x | |
if gh secret list --json name --jq '.[] | .name' | grep -q "${{ inputs.secret_name }}"; then | |
gh secret delete ${{ inputs.secret_name }} | |
fi | |