Skip to content

Commit ae45c77

Browse files
authored
Add common scripts to get original PR's information in other bot-sdk repositories (#74)
Currently, the bot-sdk repositories automatically create PRs based on updates to line-openapi. The titles and descriptions of these automatically generated PRs are sometimes filled in by maintainers, but not always. I realized that when creating a PR in the SDK repositories, we can obtain information such as the title and description by retrieving the PR information from line-openapi. I have implemented and tested a proof of concept for this. Since it seems practical, this change adds scripts to line-openapi. While we could write the same script in each SDK repository, placing it in line-openapi makes maintenance easier. Since line-openapi is registered as a submodule in the bot-sdk repositories, we can call the same script. In each SDK repository, we need to write a GitHub workflow like the following: ```diff name: Generate OpenAPI based code on: workflow_dispatch: push: branches: - master jobs: tests: name: Generate OpenAPI based code runs-on: ubuntu-latest steps: # Setup - uses: actions/checkout@v4 with: submodules: recursive - name: Update submodules run: git submodule update --remote --recursive + - uses: actions/setup-node@v4 - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 17 architecture: x64 - name: Install Dependency run: npm ci # Generate codes - run: | python3 generate-code.py - run: | diff=$(git --no-pager diff --name-only) echo "DIFF_IS_EMPTY='false'" >> $GITHUB_ENV echo "CURRENT_DATETIME=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV - if: ${{ env.DIFF_IS_EMPTY != 'true' }} run: | + # Determine Change Type via Submodule Script + CHANGE_TYPE=$(npx zx ./line-openapi/tools/determine-change-type.mjs) + echo "Determined change type: $CHANGE_TYPE" + # Determine PR title and body + if [ "$CHANGE_TYPE" == "submodule-update" ]; then + # Fetch PR info from submodule + npx zx ./line-openapi/tools/get-pr-info.mjs + PR_INFO=$(cat pr_info.json) + TITLE=$(echo "$PR_INFO" | jq -r '.title') + BODY=$(echo "$PR_INFO" | jq -r '.url')$'\n\n'$(echo "$PR_INFO" | jq -r '.body') + else + # Default PR title and body + TITLE="Codes are generated by openapi generator" + BODY="⚠Reviewer: Please edit this description to include relevant information about the changes.⚠" fi BRANCH_NAME="update-diff-${{ env.CURRENT_DATETIME }}" git config user.name github-actions git config user.email github-actions@github.com git checkout -b $BRANCH_NAME git add line-openapi git add lib/** git commit -m "Codes are generated by openapi" + git push origin $BRANCH_NAME + gh pr create -B ${{ github.ref_name }} -H $BRANCH_NAME -t "$TITLE" -b "$BODY" --label "line-openapi-update" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` As a result, we may automate PR title and description like this in each bot-sdk repository: ![image](https://github.com/user-attachments/assets/3be1c19e-2e3e-4c78-83d4-d8dfc2b3aa5e)
1 parent 6312d4b commit ae45c77

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

tools/determine-change-type.mjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env zx
2+
3+
4+
// Call this script from the parent repository
5+
// This script determines the type of change to the parent repository
6+
// by checking the latest commit message and the status of the submodule.
7+
// The possible change types are:
8+
// - submodule-update: The submodule has been updated.
9+
// - other: The parent repository has been updated, but the submodule has not been updated.
10+
// The change type is printed to the console.
11+
12+
const submoduleDir = "line-openapi";
13+
14+
async function determineChangeType() {
15+
// Get the latest commit message
16+
const { stdout: lastCommit } = await $`git log -1 --pretty=%s`;
17+
18+
// Get the status of the submodule
19+
const { stdout: submoduleStatus } = await $`git submodule status ${submoduleDir}`;
20+
const hasUpdate = submoduleStatus.trim().startsWith('+');
21+
22+
// Determine the type of change
23+
if (lastCommit.includes(submoduleDir)) {
24+
console.log("submodule-update");
25+
} else if (hasUpdate) {
26+
console.log("submodule-update");
27+
} else {
28+
console.log("other");
29+
}
30+
}
31+
32+
await determineChangeType();

tools/get-pr-info.mjs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env zx
2+
3+
import fs from "fs/promises";
4+
5+
6+
// Call this script from the parent repository
7+
// This script generates a JSON file containing information about the latest PR
8+
// that updated the submodule.
9+
// The JSON file contains the following information:
10+
// - url: The URL of the PR.
11+
// - title: The title of the PR.
12+
// - body: The body of the PR.
13+
// The JSON file is saved as pr_info.json in the parent repository.
14+
15+
const submoduleDir = "line-openapi";
16+
const repo = "line/line-openapi";
17+
18+
async function generatePrInfo() {
19+
// Change to the submodule directory
20+
cd(submoduleDir);
21+
22+
// Get the latest commit message in the submodule
23+
const { stdout: lastCommit } = await $`git log -1 --pretty=%s`;
24+
console.log("Last commit in submodule:", lastCommit.trim());
25+
26+
// Extract the PR number from the commit message
27+
const prNumberMatch = lastCommit.match(/#(\d+)/);
28+
if (!prNumberMatch) {
29+
console.error("No PR number found in submodule's latest commit. Exiting.");
30+
process.exit(1);
31+
}
32+
const prNumber = prNumberMatch[1];
33+
console.log("Detected PR number:", prNumber);
34+
35+
const prUrl = `https://github.com/${repo}/pull/${prNumber}`;
36+
console.log("Constructed PR URL:", prUrl);
37+
38+
// Get the PR title and body
39+
const prInfo = JSON.parse(await $`gh pr view ${prNumber} --repo ${repo} --json title,body`);
40+
const prTitle = prInfo.title;
41+
const prBody = prInfo.body;
42+
43+
// Save the PR information to a JSON file
44+
const output = {
45+
url: prUrl,
46+
title: prTitle,
47+
body: prBody,
48+
};
49+
await fs.writeFile("../pr_info.json", JSON.stringify(output, null, 2));
50+
console.log("PR information saved to pr_info.json");
51+
52+
// Return to the parent directory
53+
cd("..");
54+
}
55+
56+
await generatePrInfo();

0 commit comments

Comments
 (0)