Skip to content

Commit 47f19ee

Browse files
authored
Add release script (#1159)
* Release 4.7.0 * update script location * make executable * open URL if possible * Update script * update script * Update release.js * Update release.js
1 parent 79e8b9b commit 47f19ee

File tree

2 files changed

+172
-1
lines changed

2 files changed

+172
-1
lines changed

bin/release.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/usr/bin/env node
2+
3+
const { execSync } = require('child_process');
4+
const readline = require('readline');
5+
const fs = require('fs');
6+
7+
const rl = readline.createInterface({
8+
input: process.stdin,
9+
output: process.stdout
10+
});
11+
12+
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
13+
14+
const exec = (command) => {
15+
try {
16+
return execSync(command, { stdio: 'inherit' });
17+
} catch (error) {
18+
console.error(`Error executing command: ${command}`);
19+
process.exit(1);
20+
}
21+
};
22+
23+
const execWithOutput = (command) => {
24+
try {
25+
return execSync(command, { stdio: 'pipe' }).toString().trim();
26+
} catch (error) {
27+
console.error(`Error executing command: ${command}`);
28+
process.exit(1);
29+
}
30+
};
31+
32+
const updateVersionInFile = (filePath, version, patterns) => {
33+
let content = fs.readFileSync(filePath, 'utf8');
34+
35+
patterns.forEach(({ search, replace }) => {
36+
content = content.replace(
37+
search,
38+
typeof replace === 'function' ? replace(version) : replace
39+
);
40+
});
41+
42+
fs.writeFileSync(filePath, content);
43+
};
44+
45+
const updateChangelog = (version) => {
46+
const date = new Date().toISOString().split('T')[0];
47+
const content = fs.readFileSync('CHANGELOG.md', 'utf8');
48+
49+
// Update the Unreleased section
50+
let updated = content.replace(
51+
/## \[Unreleased\]/,
52+
`## [${version}] - ${date}`
53+
);
54+
55+
// Update the comparison links at the bottom
56+
const prevVersion = content.match(/compare\/(\d+\.\d+\.\d+)\.\.\.trunk/)[1];
57+
updated = updated.replace(
58+
/\[Unreleased\]: .*\n/,
59+
`[Unreleased]: https://github.com/Automattic/wordpress-activitypub/compare/${version}...trunk\n`
60+
);
61+
62+
// Add the new version comparison link
63+
const newVersionLink = `[${version}]: https://github.com/Automattic/wordpress-activitypub/compare/${prevVersion}...${version}\n`;
64+
updated = updated.replace(
65+
/<!-- Add new release below and update "Unreleased" link -->\n/,
66+
`<!-- Add new release below and update "Unreleased" link -->\n${newVersionLink}`
67+
);
68+
69+
fs.writeFileSync('CHANGELOG.md', updated);
70+
};
71+
72+
async function createRelease(version) {
73+
// Create and checkout release branch
74+
const branchName = `release/${version}`;
75+
exec(`git checkout -b ${branchName}`);
76+
77+
// Update version numbers in files
78+
updateVersionInFile('activitypub.php', version, [
79+
{
80+
search: /Version: \d+\.\d+\.\d+/,
81+
replace: `Version: ${version}`
82+
},
83+
{
84+
search: /ACTIVITYPUB_PLUGIN_VERSION', '\d+\.\d+\.\d+/,
85+
replace: `ACTIVITYPUB_PLUGIN_VERSION', '${version}`
86+
}
87+
]);
88+
89+
updateVersionInFile('readme.txt', version, [
90+
{
91+
search: /Stable tag: \d+\.\d+\.\d+/,
92+
replace: `Stable tag: ${version}`
93+
},
94+
{
95+
search: /= Unreleased =/,
96+
replace: `= ${version} =`
97+
}
98+
]);
99+
100+
// Update CHANGELOG.md
101+
updateChangelog(version);
102+
103+
// Stage and commit changes
104+
exec('git add .');
105+
exec(`git commit -m "Release ${version}"`);
106+
107+
// Push to remote
108+
exec(`git push -u origin ${branchName}`);
109+
110+
// Get current user's GitHub username
111+
const currentUser = execWithOutput('gh api user --jq .login');
112+
113+
// Create PR using GitHub CLI and capture the URL
114+
console.log('\nCreating draft PR...');
115+
const prUrl = execWithOutput(`gh pr create --title "Release ${version}" --body "Release version ${version}" --base trunk --head ${branchName} --draft --reviewer "Automattic/fediverse" --assignee "${currentUser}" --json url --jq .url`);
116+
117+
// Open PR in browser
118+
exec(`open ${prUrl}`);
119+
}
120+
121+
async function release() {
122+
try {
123+
// Check if gh CLI is installed
124+
try {
125+
execSync('gh --version', { stdio: 'ignore' });
126+
} catch (error) {
127+
console.error('GitHub CLI (gh) is not installed. Please install it first:');
128+
console.error('https://cli.github.com/');
129+
process.exit(1);
130+
}
131+
132+
// Store current branch
133+
const currentBranch = execWithOutput('git rev-parse --abbrev-ref HEAD');
134+
135+
while (true) {
136+
// Get new version
137+
const version = await question('\nWhat version would you like to release? (x.x.x): ');
138+
if (!/^\d+\.\d+\.\d+$/.test(version)) {
139+
console.error('Invalid version format. Please use x.x.x');
140+
continue;
141+
}
142+
143+
// Check if release branch already exists
144+
const branchExists = execWithOutput(`git branch --list release/${version}`);
145+
if (branchExists) {
146+
console.error(`\nError: Branch release/${version} already exists.`);
147+
// Return to original branch if we're not already there
148+
if (currentBranch !== execWithOutput('git rev-parse --abbrev-ref HEAD')) {
149+
exec(`git checkout ${currentBranch}`);
150+
}
151+
continue;
152+
}
153+
154+
// Ensure we're on trunk branch and up to date
155+
exec('git checkout trunk');
156+
exec('git pull origin trunk');
157+
158+
await createRelease(version);
159+
break;
160+
}
161+
162+
} catch (error) {
163+
console.error('An error occurred:', error);
164+
process.exit(1);
165+
} finally {
166+
rl.close();
167+
}
168+
}
169+
170+
release();

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"build": "wp-scripts build",
1515
"env-start": "wp-env start && wp-env run cli wp rewrite structure '/%year%/%monthnum%/%postname%/'",
1616
"env-stop": "wp-env stop",
17-
"env-test": "wp-env run tests-cli --env-cwd=\"wp-content/plugins/activitypub\" vendor/bin/phpunit"
17+
"env-test": "wp-env run tests-cli --env-cwd=\"wp-content/plugins/activitypub\" vendor/bin/phpunit",
18+
"release": "node bin/release.js"
1819
},
1920
"license": "MIT",
2021
"bugs": {

0 commit comments

Comments
 (0)