コンテキスト
- GitHub Organization を管理している
- リポジトリの棚卸しを効率化したい
前提
repo を複数持つ GitHub Organization があるとする
ゴール
定期的に GitHub Actions workflow として実行し、棚卸し作業指示の GitHub issue を作りたい
ざっくり設計
- 条件に当てはまる repo 一覧を取得
- issue 作成
- description には repo 一覧をタスクリストとして記載する
手段
GitHub Actions から GitHub の GraphQL API を利用する
ほかに検討した選択肢
REST API:
- curl
- JavaScript
- gh CLI
上記いずれも使い勝手はそんなに変わらない。特に今回のケースではクエリが単純なので REST API と GraphQL の間でも体験はそんなに違わないかも。
ただし別タスクなどでクエリが複雑になった場合には GraphQL のほうがクエリをシンプルに書けて、学習コストに対するトータルの見返りが大きい可能性がある。
限りなく実装な設計
ChatGPT にも考えてもらう
まず雑に投げてみる
organization repo のアーカイブ効率化する GitHub Actions 実装の相談: 直近1 ヶ月間更新のないorganization repository を取得したい。archive 対象であるこれらをdescription にタスクリストとして記載した issue を sre というリポジトリに作りたい。これを 1 ヶ月おきに実行するGitHub Actions を書いてほしい
ChatGPT による案
name: Archive Old Repositories
on:
schedule:
- cron: '0 0 1 * *' # 毎月1日の0時に実行
workflow_dispatch: # 手動実行を許可
jobs:
archive_old_repos:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: pip install requests
- name: Run script to find and archive old repositories
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
python3 - <<'EOF'
import requests
import json
from datetime import datetime, timedelta
# GitHub Personal Access Token
TOKEN = '${{ secrets.GH_TOKEN }}'
ORG_NAME = 'rindrics-sandbox-org'
SRE_REPO = 'sre'
# Calculate the date one month ago
one_month_ago = datetime.now() - timedelta(days=30)
one_month_ago_iso = one_month_ago.isoformat() + "Z"
# GraphQL query
query = """
{
organization(login: "%s") {
repositories(first: 100, orderBy: {field: UPDATED_AT, direction: ASC}) {
nodes {
name
updatedAt
}
}
}
}
""" % ORG_NAME
url = 'https://api.github.com/graphql'
headers = {
'Authorization': f'Bearer {TOKEN}',
'Content-Type': 'application/json'
}
response = requests.post(url, headers=headers, data=json.dumps({'query': query}))
if response.status_code == 200:
data = response.json()
nodes = data['data']['organization']['repositories']['nodes']
# Filter repositories updated more than 1 month ago
old_repos = [repo for repo in nodes if datetime.fromisoformat(repo['updatedAt'][:-1]) < one_month_ago]
if not old_repos:
print("No repositories found that were updated more than a month ago.")
exit(0)
# Create issue body
issue_body = "The following repositories have not been updated in the last month and are candidates for archiving:\n\n"
for repo in old_repos:
issue_body += f"- [ ] {repo['name']} (Last updated: {repo['updatedAt']})\n"
# Create an issue in the SRE repository
issue_url = f'https://api.github.com/repos/{ORG_NAME}/{SRE_REPO}/issues'
issue_data = {
'title': 'Monthly Archive Candidates',
'body': issue_body
}
issue_headers = {
'Authorization': f'token {TOKEN}',
'Content-Type': 'application/json'
}
issue_response = requests.post(issue_url, headers=issue_headers, data=json.dumps(issue_data))
if issue_response.status_code == 201:
print("Issue created successfully.")
else:
print(f"Failed to create issue: {issue_response.status_code} {issue_response.text}")
else:
print(f"Query failed to run by returning code of {response.status_code}. {response.json()}")
EOF
いくつか改善点があったので指摘
改善点があったので下記に留意して書き直してほしい:
- GraphQL を投げる部分は独立した step として分けてほしい
- new issue するアクションは独立した step として分けてほしい
- Python コードをできるだけ減らしてほしい
- 利用 action のバージョンを下記のようにアップデートしてほしい
- actions/checkout@v4
- actions/setup-python@v5
ChatGPT による案
name: Archive Old Repositories
on:
schedule:
- cron: '0 0 1 * *' # 毎月1日の0時に実行
workflow_dispatch: # 手動実行を許可
jobs:
archive_old_repos:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Query repositories
id: graphql
uses: octokit/graphql-action@v2.x
with:
query: |
query ($org: String!, $date: DateTime!) {
organization(login: $org) {
repositories(first: 100, orderBy: {field: UPDATED_AT, direction: ASC}) {
nodes {
name
updatedAt
}
}
}
}
variables: |
{
"org": "rindrics-sandbox-org",
"date": "${{ steps.date.outputs.one_month_ago }}"
}
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Set date variable
id: date
run: echo "one_month_ago=$(date -d '-1 month' --utc +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_ENV
- name: Filter old repositories and create issue body
id: create_issue_body
run: |
echo "Creating issue body..."
python3 - <<EOF
import os
import json
from datetime import datetime, timedelta
response = ${{
steps.graphql.outputs.data
}}
data = json.loads(response)
nodes = data['organization']['repositories']['nodes']
one_month_ago = datetime.strptime(os.getenv('one_month_ago'), '%Y-%m-%dT%H:%M:%SZ')
old_repos = [repo for repo in nodes if datetime.strptime(repo['updatedAt'], '%Y-%m-%dT%H:%M:%SZ') < one_month_ago]
if not old_repos:
print("No repositories found that were updated more than a month ago.")
exit(0)
issue_body = "The following repositories have not been updated in the last month and are candidates for archiving:\n\n"
for repo in old_repos:
issue_body += f"- [ ] {repo['name']} (Last updated: {repo['updatedAt']})\n"
with open('issue_body.txt', 'w') as f:
f.write(issue_body)
EOF
- name: Create issue
uses: actions-ecosystem/action-create-issue@v1.x
with:
token: ${{ secrets.GH_TOKEN }}
repository: rindrics-sandbox-org/sre
title: Monthly Archive Candidates
body: |
${{ steps.create_issue_body.outputs.issue_body }}
微修正
すこし改善点があったので直してほしい
create_issue_body
step の出力は.txt
でなく $GITHUB_OUTPUT という環境変数に出力してほしい- 各 issue description の形式は "[yyyy ${quarter_number} 棚卸し] ${repo_name} のアーカイブを検討する" の形式にしてほしい。たとえば"[2024 2Q] rindrics-sandbox-org/first-repo のアーカイブを検討する" など
- GH_TOKEN には https://github.com/actions/create-github-app-token を利用して生成したものを使ってほしい
ChatGPT による案
name: Archive Old Repositories
on:
schedule:
- cron: '0 0 1 * *' # 毎月1日の0時に実行
workflow_dispatch: # 手動実行を許可
jobs:
archive_old_repos:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate GitHub App Token
id: generate_token
uses: actions/create-github-app-token@v1.3.0
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
installation_id: ${{ secrets.INSTALLATION_ID }}
- name: Set date variable
id: date
run: |
echo "one_month_ago=$(date -d '-1 month' --utc +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_ENV
echo "current_year=$(date +'%Y')" >> $GITHUB_ENV
echo "current_quarter=Q$((($(date +%m)-1)/3+1))" >> $GITHUB_ENV
- name: Query repositories
id: graphql
uses: octokit/graphql-action@v2.x
with:
query: |
query ($org: String!, $date: DateTime!) {
organization(login: $org) {
repositories(first: 100, orderBy: {field: UPDATED_AT, direction: ASC}) {
nodes {
name
updatedAt
}
}
}
}
variables: |
{
"org": "rindrics-sandbox-org",
"date": "${{ steps.date.outputs.one_month_ago }}"
}
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Filter old repositories and create issue body
id: create_issue_body
run: |
echo "Creating issue body..."
python3 - <<EOF
import os
import json
from datetime import datetime, timedelta
response = ${{
steps.graphql.outputs.data
}}
data = json.loads(response)
nodes = data['organization']['repositories']['nodes']
one_month_ago = datetime.strptime(os.getenv('one_month_ago'), '%Y-%m-%dT%H:%M:%SZ')
old_repos = [repo for repo in nodes if datetime.strptime(repo['updatedAt'], '%Y-%m-%dT%H:%M:%SZ') < one_month_ago]
if not old_repos:
print("No repositories found that were updated more than a month ago.")
exit(0)
current_year = os.getenv('current_year')
current_quarter = os.getenv('current_quarter')
issue_body = ""
for repo in old_repos:
repo_name = repo['name']
issue_body += f"- [ ] [{current_year} {current_quarter}] {repo_name} のアーカイブを検討する (Last updated: {repo['updatedAt']})\n"
print(f"issue_body={issue_body}")
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f"issue_body={issue_body}", file=fh)
EOF
- name: Create issue
uses: actions-ecosystem/action-create-issue@v1.x
with:
token: ${{ steps.generate_token.outputs.token }}
repository: rindrics-sandbox-org/sre
title: Monthly Archive Candidates
body: ${{ steps.create_issue_body.outputs.issue_body }}
動きを見つつ修正したもの
name: Create Issue for Archive Candidate Repositories
on:
schedule:
- cron: '0 0 1 * *' # 毎月1日の0時に実行
workflow_dispatch: # 手動実行を許可
jobs:
create_issue_with_archive_candidate_repos:
runs-on: ubuntu-latest
env:
month_diff: 1
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate GitHub App Token for Query
id: generate_query_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID_REPO_LISTER }}
private-key: ${{ secrets.PRIVATE_KEY_REPO_LISTER }}
- name: Generate GitHub App Token for Issue Creation
id: generate_issue_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID_ISSUE_CREATOR }}
private-key: ${{ secrets.PRIVATE_KEY_ISSUE_CREATOR }}
- name: Set date variable
id: date
run: |
echo "month_ago=$(date -d "-$month_diff month" --utc +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_ENV
echo "current_year=$(date +'%Y')" >> $GITHUB_ENV
echo "current_quarter=$((($(date +%m)-1)/3+1))Q" >> $GITHUB_ENV
- name: Query repositories
id: graphql
uses: octokit/graphql-action@v2.3.2
with:
query: |
query ($org: String!) {
organization(login: $org) {
repositories(first: 100, orderBy: {field: UPDATED_AT, direction: ASC}) {
nodes {
name
updatedAt
}
}
}
}
variables: |
{
"org": "rindrics-sandbox-org"
}
env:
GITHUB_TOKEN: ${{ steps.generate_query_token.outputs.token }}
- name: Filter old repositories and create issue data
id: create_issue_data
run: |
echo "Creating issue body..."
python3 - <<EOF
import os
from datetime import datetime, timedelta
response = ${{
steps.graphql.outputs.data
}}
nodes = response['organization']['repositories']['nodes']
month_ago = datetime.strptime(os.getenv('month_ago'), '%Y-%m-%dT%H:%M:%SZ')
month_diff = os.getenv('month_diff')
old_repos = [repo for repo in nodes if datetime.strptime(repo['updatedAt'], '%Y-%m-%dT%H:%M:%SZ') < month_ago]
if not old_repos:
print(f"No repositories found that were updated more than {month_diff} months ago.")
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
fh.write(f"has_old_repos=false\n")
exit(0)
current_year = os.getenv('current_year')
current_quarter = os.getenv('current_quarter')
year_quarter = f"[{current_year} {current_quarter}]"
issue_title = f"{year_quarter} リポジトリ棚卸し"
issue_body = f"下記は直近 {month_diff} か月間で更新のないリポジトリのリストです。アーカイブを検討してください。\n"
for repo in old_repos:
repo_name = repo['name']
issue_body += f"- [ ] {year_quarter} {repo_name} のアーカイブを検討する\n"
# Write the issue title and body to the output environment variable
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
fh.write(f"has_old_repos=true\n")
fh.write(f"issue_title={issue_title}\n")
fh.write(f"issue_body<<EOF\n{issue_body}\nEOF\n")
EOF
- name: Create issue
if: ${{ steps.create_issue_data.outputs.has_old_repos }} == 'true'
uses: actions-ecosystem/action-create-issue@v1
with:
github_token: ${{ steps.generate_issue_token.outputs.token }}
repo: rindrics-sandbox-org/sre
title: ${{ steps.create_issue_data.outputs.issue_title }}
body: ${{ steps.create_issue_data.outputs.issue_body }}
ここまでで、下記のように issue がつくられるようになった
(リポジトリがぜんぶ作りたてなので動作確認のためにクエリ条件を ”直近 0 か月以上更新がないリポジトリ” にしている)
仕様変更
タスクリストではなく、子 issue まで一気に作ってしまうことにした
- もともと issue description にタスクリストを書くようにしていたのは必要に応じて issue 化できるようにだった
- しかし各子 issue での「アーカイブを検討」でも定型作業がありそう:
- リポジトリオーナーに利用状況を確認してもらう
- アーカイブ可否を返信してもらう
これらを反映していく
仕様変更のプロンプト
(実際のプロンプトにはここにコード)
上記のコードで、アーカイブ対象リポジトリをタスクリストに持った issue を作れた。
しかし仕様変更したい。
変更内容:
- description について、アーカイブ対象リポジトリのタスクリストではなく、各アーカイブ対象ごとに issue をつくり、そのリストにしたい
- 各アーカイブ対象の issue description は下記の通り:
"本リポジトリは直近{month}ヶ月間で更新がないようです。利用状況を確認し、アーカイブ可能な場合には {my_team} にご連絡ください。@{owner_team}\n- 依頼背景: {親 issue の full URL}において Organization リポジトリの棚卸しをしており、利用されなくなったリポジトリのアーカイブを検討しています。"- 各アーカイブ対象の issue 作成先はそれぞれの repo
方針:
issue data を作っているステップを下記のように分割する:- old_repos のリストを作るステップ
- old_repos のリストの数だけ issue dataを作るステップ
- 出力: child_issue_data = {repo, issue_title, issue_body} のリスト
- child_issue_data (matrix?)に対して issue を作るステップ
- 出力: repo 名と issue URL のマップ
- repo 名と issue URL のマップから親 issue のデータを作るステップ
- 出力: parent_issue_data = {issue_title, issue_body}
- parent_issue_data から issue を一つ作るステップ
動かしながら微(大)修正してできた action は下記の通り(ちょっと長くなってしまったが)
workflow.yml
name: Create Issue for Archive Candidate Repositories
on:
schedule:
- cron: '0 0 1 * *'
workflow_dispatch:
env:
my_org: rindrics-sandbox-org
my_repo: sre # repository name to which epic issue is created
my_team: sre # team to whom epic issue is assigned
threshold_last_update: 3 # if repo `updatedAt` is greater than this parameter, it is assumed as "inactive"
jobs:
get_archive_candidates:
runs-on: ubuntu-latest
outputs:
has_old_repos: ${{ steps.get_archive_candidates.outputs.has_old_repos }}
old_repos: ${{ steps.get_archive_candidates.outputs.old_repos }}
current_year: ${{ env.current_year }}
current_quarter: ${{ env.current_quarter }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate GitHub App Token
id: generate_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID_TEAM_READER }}
private-key: ${{ secrets.PRIVATE_KEY_TEAM_READER }}
- name: Set date variable
id: date
run: |
echo "month_ago=$(date -d '-${{ env.threshold_last_update }} month' --utc +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_ENV
echo "current_year=$(date +'%Y')" >> $GITHUB_ENV
echo "current_quarter=$((($(date +%m)-1)/3+1))Q" >> $GITHUB_ENV
- name: Query all repositories under organization
id: query_repo
uses: octokit/graphql-action@v2.3.2
with:
query: |
query ($org: String!) {
organization(login: $org) {
repositories(first: 100, orderBy: {field: UPDATED_AT, direction: ASC}) {
nodes {
name
updatedAt
}
}
}
}
variables: |
{
"org": "${{ env.my_org }}"
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Query teams
id: query_teams
uses: octokit/graphql-action@v2.3.2
with:
query: |
query ($org: String!) {
organization(login: $org) {
teams(first: 100) {
edges {
node {
slug
name
repositories(first: 100) {
edges {
node {
name
}
permission
}
}
}
}
}
}
}
variables: |
{
"org": ${{ env.my_org }}
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Get archive candidate repos
id: get_archive_candidates
run: |
echo "Extracting old repositories..."
python3 - <<EOF
import os
from datetime import datetime, timedelta
import json
# Repositories response from query_repo step
repos_response = ${{
steps.query_repo.outputs.data
}}
repos_nodes = repos_response['organization']['repositories']['nodes']
# Teams response from query_teams step
teams_response = ${{
steps.query_teams.outputs.data
}}
teams_edges = teams_response['organization']['teams']['edges']
month_ago = datetime.strptime(os.getenv('month_ago'), '%Y-%m-%dT%H:%M:%SZ')
# Build a map of teams and their repository permissions
team_repo_permissions = {}
for team in teams_edges:
team_slug = team['node']['slug']
for repo_edge in team['node']['repositories']['edges']:
repo_name = repo_edge['node']['name']
permission = repo_edge['permission']
if permission == 'ADMIN':
if repo_name not in team_repo_permissions:
team_repo_permissions[repo_name] = []
team_repo_permissions[repo_name].append(team_slug)
# Filter old repositories and find admin teams
old_repos = [
{
'name': repo['name'],
'admin_teams': team_repo_permissions.get(repo['name'], [])
}
for repo in repos_nodes if datetime.strptime(repo['updatedAt'], '%Y-%m-%dT%H:%M:%SZ') < month_ago
]
if not old_repos:
print(f"No repositories found that were updated more than {os.getenv('threshold_last_update')} months ago.")
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
fh.write(f"has_old_repos=false\n")
exit(0)
old_repos_str = json.dumps(old_repos)
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
fh.write(f"has_old_repos=true\n")
fh.write(f"old_repos={old_repos_str}\n")
EOF
create_issues:
runs-on: ubuntu-latest
needs: get_archive_candidates
if: needs.get_archive_candidates.outputs.has_old_repos == 'true'
env:
old_repos: ${{ needs.get_archive_candidates.outputs.old_repos }}
current_year: ${{ needs.get_archive_candidates.outputs.current_year }}
current_quarter: ${{ needs.get_archive_candidates.outputs.current_quarter }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate GitHub App Token
id: generate_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID_ISSUE_CREATOR }}
private-key: ${{ secrets.PRIVATE_KEY_ISSUE_CREATOR }}
- name: Get repository ID
id: get_repo_id
uses: octokit/graphql-action@v2.3.2
with:
query: |
query($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
id
}
}
variables: |
{
"owner": ${{ env.my_org }},
"name": ${{ env.my_repo }}
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Create parent issue
id: create_parent_issue
uses: octokit/graphql-action@v2.3.2
with:
query: |
mutation($repoId: ID!, $title: String!, $body: String!) {
createIssue(input: {repositoryId: $repoId, title: $title, body: $body}) {
issue {
url
id
}
}
}
variables: |
{
"repoId": "${{ fromJSON(steps.get_repo_id.outputs.data).repository.id }}",
"title": "[${{ env.current_year }} ${{ env.current_quarter }}] リポジトリ棚卸し",
"body": ""
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Create child issue data
id: create_child_issue_data
run: |
echo "Creating child issue data..."
python3 - <<EOF
import os
import json
old_repos_str = os.getenv('old_repos')
old_repos = json.loads(old_repos_str)
threshold_last_update = os.getenv('threshold_last_update')
my_org = os.getenv('my_org')
my_team = os.getenv('my_team')
current_year = os.getenv('current_year')
current_quarter = os.getenv('current_quarter')
year_quarter = f"[{current_year} {current_quarter} repo 棚卸し]"
parent_issue_url = os.getenv('parent_issue_url')
child_issue_data_list = []
for repo in old_repos:
repo_name = repo['name']
admin_teams = [f"{my_org}/{t}" for t in repo['admin_teams']]
admin_team_mentions = " ".join([f"@{t}" for t in admin_teams])
issue_title = f"{year_quarter} 本リポジトリのアーカイブを検討する"
issue_body = f"本リポジトリは直近 {threshold_last_update} か月間で更新がないようです。利用状況を確認し、アーカイブ可能な場合には @{my_org}/{my_team} にご連絡ください。{admin_team_mentions}\n- 依頼背景: {parent_issue_url} において Organization リポジトリの棚卸しをしており、利用されなくなったリポジトリのアーカイブを検討しています。"
issue_data = {'repo': f"{my_org}/{repo_name}", 'admin_team_mentions': f"{admin_team_mentions}", 'issue_title': issue_title, 'issue_body': issue_body}
child_issue_data_list.append(issue_data)
child_issue_data_str = json.dumps(child_issue_data_list)
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
fh.write(f"child_issue_data={child_issue_data_str}\n")
EOF
env:
parent_issue_url: ${{ fromJSON(steps.create_parent_issue.outputs.data).createIssue.issue.url }}
- name: Create child issues
id: create_child_issues
run: |
echo "Creating child issues..."
echo "child_issue_urls<<EOF" >> $GITHUB_ENV
issue_data='${{ steps.create_child_issue_data.outputs.child_issue_data }}'
length=$(echo $issue_data | jq length)
for i in $(seq 0 $(($length - 1))); do
repo=$(echo $issue_data | jq -r .[$i].repo)
issue_title=$(echo $issue_data | jq -r .[$i].issue_title)
issue_body=$(echo $issue_data | jq -r .[$i].issue_body)
issue_url=$(gh issue create --repo "$repo" --title "$issue_title" --body "$issue_body" 2>&1)
if [ $? -ne 0 ]; then
echo "Failed to create issue for $repo. Error: $issue_url"
exit 1
fi
echo $issue_url
echo "- [ ] $issue_url\n" >> $GITHUB_ENV
done
echo EOF >> $GITHUB_ENV
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Update parent issue description
uses: octokit/graphql-action@v2.3.2
with:
query: |
mutation ($id: ID!, $body: String!) {
updateIssue(input: {id: $id, body: $body}) {
issue {
body
}
}
}
variables: |
{
"id": "${{ fromJSON(steps.create_parent_issue.outputs.data).createIssue.issue.id }}",
"body": "下記は直近 ${{ env.threshold_last_update }} か月間で更新のないリポジトリのリストです。アーカイブを検討してください。\n${{ env.child_issue_urls }}"
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
できたものの仕様
入力
-
threshold_inactive
: 「古い」と見なす最終更新日の閾値(単位: ヶ月) -
my_team
: アーカイブタスクに責任を持つチーム。アーカイビング検討を依頼する子 issue の description にメンションが記載される
出力
なし
副作用
Workflow 実行 repo に作られる親 issue
動作確認に使った repo が作りたてなのでクエリ対象を 直近 0 ヶ月間の間更新がないリポジトリ
としている(でないとなにも引っかからないため)