Skip to content

Commit

Permalink
chore(ci): refine release process (#238)
Browse files Browse the repository at this point in the history
* chore(ci): refine release process

* chore: create tag if env var is given

* chore: revert test code

* Update scripts/common.ts

Co-authored-by: Clément Vannicatte <[email protected]>

* chore: add comment

Co-authored-by: Clément Vannicatte <[email protected]>
  • Loading branch information
eunjae-lee and shortcuts authored Mar 10, 2022
1 parent e8e25ab commit 2481779
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 40 deletions.
1 change: 1 addition & 0 deletions .github/workflows/process-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ jobs:
env:
EVENT_NUMBER: ${{ github.event.issue.number }}
GITHUB_TOKEN: ${{ secrets.TOKEN_RELEASE_BOT }}
VERSION_TAG_ON_RELEASE: $${{ secrets.VERSION_TAG_ON_RELEASE }}
26 changes: 23 additions & 3 deletions scripts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(ROOT_DIR, '.env');

export const GENERATORS: Record<string, Generator> = {
// Default `algoliasearch` package as it's built similarly to generated clients
'javascript-algoliasearch': {
Expand Down Expand Up @@ -65,7 +67,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}-`)
);
Expand All @@ -74,8 +86,16 @@ 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}`;
}

// GitHub Action provides a default token for authentication
// https://docs.github.com/en/actions/security-guides/automatic-token-authentication
// But it has access to only the self repository.
// If we want to do something like pushing commits to other repositories,
// we need to specify a token with more access.
return token
? `https://${token}:${token}@github.com/${gitHost}/${gitRepoId}`
: `https://github.com/${gitHost}/${gitRepoId}`;
};

export function createGeneratorKey({
language,
Expand Down
4 changes: 2 additions & 2 deletions scripts/release/create-release-issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
79 changes: 46 additions & 33 deletions scripts/release/process-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@ 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 {
RELEASED_TAG,
OWNER,
REPO,
getMarkdownSection,
getTargetBranch,
getGitAuthor,
getTargetBranch,
} 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.');
Expand All @@ -42,11 +48,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) => {
Expand All @@ -58,6 +71,7 @@ function getVersionsToRelease(issueBody: string): VersionsToRelease {
versionsToRelease[lang] = {
current,
next,
dateStamp,
};
});

Expand Down Expand Up @@ -129,17 +143,10 @@ async function processRelease(): Promise<void> {

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(
Expand All @@ -149,9 +156,7 @@ async function processRelease(): Promise<void> {
? (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),
Expand All @@ -162,22 +167,7 @@ async function processRelease(): Promise<void> {
[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.
Expand All @@ -186,14 +176,37 @@ async function processRelease(): Promise<void> {
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 --branch ${targetBranch} ${gitHubUrl} ${tempGitDir}`
);

await run(`cp -r ${clientPath}/ ${tempGitDir}`);
await configureGitHubAuthor(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,
});
if (process.env.VERSION_TAG_ON_RELEASE === 'true') {
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
Expand Down
2 changes: 0 additions & 2 deletions scripts/release/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,4 @@ export default {
`To skip this release, just close the issue.`,
`- [ ] ${APPROVED}`,
].join('\n'),

commitMessage: `chore: update versions and submodules`,
};

0 comments on commit 2481779

Please sign in to comment.