Skip to content

Commit

Permalink
Add workflow to transfer issues from another mozilla repository (#1591)
Browse files Browse the repository at this point in the history
* Add workflow to transfer issues from another mozilla repository

* use PAT

* Make script locally executable. Add ability to run for specific issue.

* fix docs and typo in env variable

* Add prefill link
  • Loading branch information
KevinMind committed Mar 26, 2024
1 parent ed00a48 commit 217bc44
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 0 deletions.
75 changes: 75 additions & 0 deletions .github/workflows/transfer-issues.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Transfer issues

# To run this action. You need to do the following:
#
# 1. Create a personal access token (Classic) with the `repo` and `read:org` scopes.
#
# URL: https://github.com/settings/tokens/new?description=transfer-issues-token&scopes=repo,read:org
#
# 2. Authorize the token for use with [SAML](https://github.com/latest/authentication/authenticating-with-saml-single-sign-on/authorizing-a-personal-access-token-for-use-with-saml-single-sign-on) on the `mozilla` org.
#
# 3. Create a secret in the repository with whatever name you want, and paste the token as the value.
#
# ex: $ gh secret set <secret-name> --body "<token_value>
#
# 4. Run the action with the secret name as the `secret_name` input.
#
# ex: `gh secret set <secret-name> --body "<token_value>" && gh workflow run 90730614 --field count="10" --field from_name="addons-server" --field secret_name="<secret-name>"`
#
# 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
issue_number:
description: "the issue number to transfer. Overrides count if set."
required: false
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

concurrency:
group: transfer
cancel-in-progress: true

jobs:
fetch_issues:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Transfer issues
env:
ALLOWED_REPOS: "addons-server,addons-frontend"
GH_TOKEN: ${{ secrets[format('{0}', inputs.secret_name)] }}
FROM_NAME: ${{ inputs.from_name }}
REPOSITORY_OWNER: ${{ github.repository_owner }}
TO_NAME: ${{ github.event.repository.name }}
COUNT: ${{ inputs.count }}
ISSUE_NUMBER: ${{ inputs.issue_number }}
shell: bash
run: ./scripts/transfer-issues.sh

- 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
125 changes: 125 additions & 0 deletions scripts/transfer-issues.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash

set -x

COUNT=${COUNT:-1}
ISSUE_NUMBER=${ISSUE_NUMBER:-}

set -u

# Required environment variables
# GITHUB_TOKEN: GitHub token with repo scope
# REPOSITORY_OWNER: GitHub repository owner
# FROM_NAME: Repository name to transfer issues from
# TO_NAME: Repository name to transfer issues to
# ALLOWED_REPOS: Comma-separated list of allowed repositories

# Optional environment variables
# ISSUE_NUMBER: Issue number to transfer (will nullify COUNT)
# COUNT: Number of issues to transfer

FROM_REPO="$REPOSITORY_OWNER/$FROM_NAME"
TO_REPO="$REPOSITORY_OWNER/$TO_NAME"

echo """
REPOSITORY_OWNER: $REPOSITORY_OWNER
FROM_NAME: $FROM_NAME
TO_NAME: $TO_NAME
ALLOWED_REPOS: $ALLOWED_REPOS
FROM_REPO: $FROM_REPO
TO_REPO: $TO_REPO
ISSUE_NUMBER: $ISSUE_NUMBER
COUNT: $COUNT
"""

auth_status=$(gh auth status 2>&1)

if [[ "$auth_status" == *"You are not logged into any GitHub hosts."* ]]; then
echo "Error: $auth_status"
exit 1
fi

if [[ ! "$ALLOWED_REPOS" =~ (^|,)"$FROM_NAME"(,|$) ]]; then
echo "Invalid FROM_NAME "$FROM_NAME". Exiting..."
exit 1
fi

function get_single_issue() {
local issues_query="""
query {
repository(owner: \"$REPOSITORY_OWNER\", name: \"$FROM_NAME\") {
issue(number: $ISSUE_NUMBER) {
id
}
}
}
"""

local issues=$(gh api graphql -f query="$issues_query" --jq '.data.repository.issue.id')

echo "$issues"
}

function get_multiple_issues() {
local issues_query="""
query {
repository(owner: \"$REPOSITORY_OWNER\", name: \"$FROM_NAME\") {
issues(first: $COUNT, orderBy: {field: CREATED_AT, direction: ASC}) {
nodes {
id
}
}
}
}
"""

local issues=$(gh api graphql -f query="$issues_query" --jq '.data.repository.issues.nodes[].id')

echo "$issues"
}

if [[ -n "$ISSUE_NUMBER" ]]; then
echo "Transferring issue $ISSUE_NUMBER from \"$FROM_REPO\" to \"$TO_REPO\""
issues=$(get_single_issue)
else
echo "Transferring $COUNT issues from \"$FROM_REPO\" to \"$TO_REPO\""
issues=$(get_multiple_issues)
fi

transfer_mutation="mutation {"

new_issues_counter=1

repository_id=$(gh repo view "$TO_REPO" --json id --jq '.id')

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}')

repo_label="repository:$FROM_NAME"

gh label create \"$repo_label\" -R "$TO_REPO" --force

label_id=$(gh api /repos/$TO_REPO/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 <<< $(echo "$new_issues" | jq -r '.id')

label_mutation+=" }"

gh api graphql -f query="$label_mutation"

echo "$new_issues" | jq -r '.url'

0 comments on commit 217bc44

Please sign in to comment.