From 340682dff956094ff17552f4790c1c6feb7db105 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Mon, 7 Mar 2022 15:47:52 +0100 Subject: [PATCH 1/6] chore(ci): update release process regarding the removal of submodules --- scripts/common.ts | 19 +++++++-- scripts/release/process-release.ts | 64 +++++++++++++++--------------- scripts/release/text.ts | 2 - 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/scripts/common.ts b/scripts/common.ts index 53ebd7dd07..dc9a40e0c7 100644 --- a/scripts/common.ts +++ b/scripts/common.ts @@ -65,7 +65,17 @@ export function splitGeneratorKey(generatorKey: string): Generator { return { language, client, key: generatorKey }; } -export function getGitHubUrl(lang: string): string { +type GitHubUrl = ( + lang: string, + options?: { + token?: string; + } +) => string; + +export const getGitHubUrl: GitHubUrl = ( + lang: string, + { token } = {} +): string => { const entry = Object.entries(openapitools['generator-cli'].generators).find( (_entry) => _entry[0].startsWith(`${lang}-`) ); @@ -74,8 +84,11 @@ export function getGitHubUrl(lang: string): string { throw new Error(`\`${lang}\` is not found from \`openapitools.json\`.`); } const { gitHost, gitRepoId } = entry[1]; - return `https://github.com/${gitHost}/${gitRepoId}`; -} + + return token + ? `https://${token}:${token}@github.com/${gitHost}/${gitRepoId}` + : `https://github.com/${gitHost}/${gitRepoId}`; +}; export function createGeneratorKey({ language, diff --git a/scripts/release/process-release.ts b/scripts/release/process-release.ts index b8e4dd819c..57e66cded8 100755 --- a/scripts/release/process-release.ts +++ b/scripts/release/process-release.ts @@ -13,7 +13,6 @@ import { OWNER, REPO, getMarkdownSection, - getTargetBranch, getGitAuthor, } from './common'; import TEXT from './text'; @@ -42,11 +41,18 @@ type VersionsToRelease = { [lang: string]: { current: string; next: string; + dateStamp: string; }; }; +function getDateStamp(): string { + return new Date().toISOString().split('T')[0]; +} + function getVersionsToRelease(issueBody: string): VersionsToRelease { const versionsToRelease: VersionsToRelease = {}; + const dateStamp = getDateStamp(); + getMarkdownSection(issueBody, TEXT.versionChangeHeader) .split('\n') .forEach((line) => { @@ -58,6 +64,7 @@ function getVersionsToRelease(issueBody: string): VersionsToRelease { versionsToRelease[lang] = { current, next, + dateStamp, }; }); @@ -129,17 +136,10 @@ async function processRelease(): Promise { for (const lang of langsToReleaseOrUpdate) { // prepare the submodule - const clientPath = toAbsolutePath(getLanguageFolder(lang)); - const targetBranch = getTargetBranch(lang); - await run(`git checkout ${targetBranch}`, { cwd: clientPath }); - await run(`git pull origin ${targetBranch}`, { cwd: clientPath }); - console.log(`Generating ${lang} client(s)...`); console.log(await run(`yarn cli generate ${lang}`)); - const dateStamp = new Date().toISOString().split('T')[0]; - const currentVersion = versionsToRelease[lang].current; - const nextVersion = versionsToRelease[lang].next; + const { current, next, dateStamp } = versionsToRelease[lang]; // update changelog const changelogPath = toAbsolutePath( @@ -149,9 +149,7 @@ async function processRelease(): Promise { ? (await fsp.readFile(changelogPath)).toString() : ''; const changelogHeader = willReleaseLibrary(lang) - ? `## [v${nextVersion}](${getGitHubUrl( - lang - )}/compare/v${currentVersion}...v${nextVersion})` + ? `## [v${next}](${getGitHubUrl(lang)}/compare/v${current}...v${next})` : `## ${dateStamp}`; const newChangelog = getMarkdownSection( getMarkdownSection(issueBody, TEXT.changelogHeader), @@ -162,38 +160,40 @@ async function processRelease(): Promise { [changelogHeader, newChangelog, existingContent].join('\n\n') ); - // commit changelog and the generated client - await configureGitHubAuthor(clientPath); - await run(`git add .`, { cwd: clientPath }); - if (willReleaseLibrary(lang)) { - await execa('git', ['commit', '-m', `chore: release ${nextVersion}`], { - cwd: clientPath, - }); - await execa('git', ['tag', `v${nextVersion}`], { cwd: clientPath }); - } else { - await execa('git', ['commit', '-m', `chore: update repo ${dateStamp}`], { - cwd: clientPath, - }); - } - - // add the new reference of the submodule in the monorepo - await run(`git add ${getLanguageFolder(lang)}`); + await run(`git add ${changelogPath}`); } // We push commits from submodules AFTER all the generations are done. // Otherwise, we will end up having broken release. for (const lang of langsToReleaseOrUpdate) { const clientPath = toAbsolutePath(getLanguageFolder(lang)); - const targetBranch = getTargetBranch(lang); - await run(`git push origin ${targetBranch}`, { cwd: clientPath }); + const gitHubUrl = getGitHubUrl(lang, { token: process.env.GITHUB_TOKEN }); + const tempGitDir = `${process.env.RUNNER_TEMP}/${lang}`; + await run(`rm -rf ${tempGitDir}`); + await run(`git clone --depth 1 ${gitHubUrl} ${tempGitDir}`); + + await run(`cp -r ${clientPath}/ ${tempGitDir}`); + await run(`git add .`, { cwd: tempGitDir }); + + const { next, dateStamp } = versionsToRelease[lang]; + if (willReleaseLibrary(lang)) { - await run('git push --tags', { cwd: clientPath }); + await execa('git', ['commit', '-m', `chore: release ${next}`], { + cwd: tempGitDir, + }); + await execa('git', ['tag', `v${next}`], { cwd: tempGitDir }); + await run(`git push --tags`, { cwd: tempGitDir }); + } else { + await execa('git', ['commit', '-m', `chore: update repo ${dateStamp}`], { + cwd: tempGitDir, + }); } + await run(`git push`, { cwd: tempGitDir }); } // Commit and push from the monorepo level. - await execa('git', ['commit', '-m', TEXT.commitMessage]); + await execa('git', ['commit', '-m', `chore: release ${getDateStamp()}`]); await run(`git push`); // remove old `released` tag diff --git a/scripts/release/text.ts b/scripts/release/text.ts index 27d74255ba..4a2a2d6b40 100644 --- a/scripts/release/text.ts +++ b/scripts/release/text.ts @@ -23,6 +23,4 @@ export default { `To skip this release, just close the issue.`, `- [ ] ${APPROVED}`, ].join('\n'), - - commitMessage: `chore: update versions and submodules`, }; From 7319fa52f0e881c87edbe2a2cc4120b6eb35c715 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Mon, 7 Mar 2022 16:33:14 +0100 Subject: [PATCH 2/6] chore(ci): add path to dotenv --- scripts/common.ts | 2 ++ scripts/release/create-release-issue.ts | 4 ++-- scripts/release/process-release.ts | 10 ++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/common.ts b/scripts/common.ts index dc9a40e0c7..5118090ce0 100644 --- a/scripts/common.ts +++ b/scripts/common.ts @@ -13,6 +13,8 @@ export const DOCKER = Boolean(process.env.DOCKER); // This script is run by `yarn workspace ...`, which means the current working directory is `./script` export const ROOT_DIR = path.resolve(process.cwd(), '..'); +export const ROOT_ENV_PATH = path.resolve(process.cwd(), '..', '.env'); + export const GENERATORS: Record = { // Default `algoliasearch` package as it's built similarly to generated clients 'javascript-algoliasearch': { diff --git a/scripts/release/create-release-issue.ts b/scripts/release/create-release-issue.ts index c2dc26288b..be1a01f7c5 100755 --- a/scripts/release/create-release-issue.ts +++ b/scripts/release/create-release-issue.ts @@ -3,12 +3,12 @@ import { Octokit } from '@octokit/rest'; import dotenv from 'dotenv'; import semver from 'semver'; -import { GENERATORS, LANGUAGES, run } from '../common'; +import { GENERATORS, LANGUAGES, ROOT_ENV_PATH, run } from '../common'; import { RELEASED_TAG, MAIN_BRANCH, OWNER, REPO } from './common'; import TEXT from './text'; -dotenv.config(); +dotenv.config({ path: ROOT_ENV_PATH }); type Version = { current: string; diff --git a/scripts/release/process-release.ts b/scripts/release/process-release.ts index 57e66cded8..ff23eab821 100755 --- a/scripts/release/process-release.ts +++ b/scripts/release/process-release.ts @@ -5,7 +5,13 @@ import dotenv from 'dotenv'; import execa from 'execa'; import openapitools from '../../openapitools.json'; -import { toAbsolutePath, run, exists, getGitHubUrl } from '../common'; +import { + ROOT_ENV_PATH, + toAbsolutePath, + run, + exists, + getGitHubUrl, +} from '../common'; import { getLanguageFolder } from '../config'; import { @@ -17,7 +23,7 @@ import { } from './common'; import TEXT from './text'; -dotenv.config(); +dotenv.config({ path: ROOT_ENV_PATH }); if (!process.env.GITHUB_TOKEN) { throw new Error('Environment variable `GITHUB_TOKEN` does not exist.'); From 5dfa695427a642af556fd0114205184d3e05e76c Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Mon, 7 Mar 2022 16:44:06 +0100 Subject: [PATCH 3/6] chore(ci): test code --- config/release.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/release.config.json b/config/release.config.json index 153e66e04e..47ae97a4cd 100644 --- a/config/release.config.json +++ b/config/release.config.json @@ -1,7 +1,7 @@ { "releasedTag": "released", "mainBranch": "main", - "owner": "algolia", + "owner": "eunjae-lee", "repo": "api-clients-automation", "targetBranch": { "javascript": "next", From b1deb8f04f04ce40d0583399c259dd5cc487c7ce Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Mon, 7 Mar 2022 16:57:53 +0100 Subject: [PATCH 4/6] chore(ci): configure github author at temp repositories --- scripts/release/process-release.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/release/process-release.ts b/scripts/release/process-release.ts index ff23eab821..53539a8863 100755 --- a/scripts/release/process-release.ts +++ b/scripts/release/process-release.ts @@ -180,6 +180,7 @@ async function processRelease(): Promise { await run(`git clone --depth 1 ${gitHubUrl} ${tempGitDir}`); await run(`cp -r ${clientPath}/ ${tempGitDir}`); + await configureGitHubAuthor(tempGitDir); await run(`git add .`, { cwd: tempGitDir }); const { next, dateStamp } = versionsToRelease[lang]; From d17b437859234bde1ff0a1cfaddb71aa5e0ff5b8 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Mon, 7 Mar 2022 17:05:57 +0100 Subject: [PATCH 5/6] chore(ci): check out to target branch for generated repos --- scripts/release/process-release.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/release/process-release.ts b/scripts/release/process-release.ts index 53539a8863..766cfee50c 100755 --- a/scripts/release/process-release.ts +++ b/scripts/release/process-release.ts @@ -20,6 +20,7 @@ import { REPO, getMarkdownSection, getGitAuthor, + getTargetBranch, } from './common'; import TEXT from './text'; @@ -173,11 +174,13 @@ async function processRelease(): Promise { // Otherwise, we will end up having broken release. for (const lang of langsToReleaseOrUpdate) { const clientPath = toAbsolutePath(getLanguageFolder(lang)); + const targetBranch = getTargetBranch(lang); const gitHubUrl = getGitHubUrl(lang, { token: process.env.GITHUB_TOKEN }); const tempGitDir = `${process.env.RUNNER_TEMP}/${lang}`; await run(`rm -rf ${tempGitDir}`); await run(`git clone --depth 1 ${gitHubUrl} ${tempGitDir}`); + await run(`git checkout ${targetBranch}`); await run(`cp -r ${clientPath}/ ${tempGitDir}`); await configureGitHubAuthor(tempGitDir); From b5b9619874638b0edccf0879290c43501ba08312 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Mon, 7 Mar 2022 17:48:25 +0100 Subject: [PATCH 6/6] chore(ci): clone target branch directly --- scripts/release/process-release.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/release/process-release.ts b/scripts/release/process-release.ts index 766cfee50c..9734519ed6 100755 --- a/scripts/release/process-release.ts +++ b/scripts/release/process-release.ts @@ -179,8 +179,9 @@ async function processRelease(): Promise { const gitHubUrl = getGitHubUrl(lang, { token: process.env.GITHUB_TOKEN }); const tempGitDir = `${process.env.RUNNER_TEMP}/${lang}`; await run(`rm -rf ${tempGitDir}`); - await run(`git clone --depth 1 ${gitHubUrl} ${tempGitDir}`); - await run(`git checkout ${targetBranch}`); + await run( + `git clone --depth 1 --branch ${targetBranch} ${gitHubUrl} ${tempGitDir}` + ); await run(`cp -r ${clientPath}/ ${tempGitDir}`); await configureGitHubAuthor(tempGitDir);