Skip to content

Commit

Permalink
Configurable Git commit, user and email
Browse files Browse the repository at this point in the history
- Add support for configuring the Git commit message, user name and user email.
- Run `npm audit fix` to resolve vulnerability.
- Fix prettier complaining about line-endings on Windows.
- Skip test that is not supported on Windows.

Relates to benchmark-action#234.
  • Loading branch information
martincostello committed Aug 13, 2024
1 parent fe4e90e commit 785538a
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 47 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
"@typescript-eslint/switch-exhaustiveness-check": "error"
"@typescript-eslint/switch-exhaustiveness-check": "error",
"prettier/prettier": ["error", { "endOfLine": "auto" }]
}
},
{
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,26 @@ which means there is no limit.

If set to `true`, the workflow will skip fetching branch defined with the `gh-pages-branch` variable.

#### `commit-message` (Optional)

- Type: String
- Default: `add ${name} (${tool}) benchmark result for ${commit}`

Overrides the message to use when committing the benchmark results to Git.

#### `commit-user-name` (Optional)

- Type: String
- Default: `github-action-benchmark`

Specifies the value to use for `user.name` when committing the benchmark results to Git.

#### `commit-user-email` (Optional)

- Type: String
- Default: `[email protected]`

Specifies the value to use for `user.email` when committing the benchmark results to Git.

### Action outputs

Expand Down
9 changes: 9 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ inputs:
max-items-in-chart:
description: 'Max data points in a benchmark chart to avoid making the chart too busy. Value must be unsigned integer. No limit by default'
required: false
commit-message:
description: 'Optional commit message to use for Git commits'
required: false
commit-user-name:
description: 'Optional user name to use for Git commits'
required: false
commit-user-email:
description: 'Optional email address to use for Git commits'
required: false

runs:
using: 'node20'
Expand Down
28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export interface Config {
externalDataJsonPath: string | undefined;
maxItemsInChart: number | null;
ref: string | undefined;
commitMessage?: string;
commitUserName?: string;
commitUserEmail?: string;
}

export const VALID_TOOLS = [
Expand Down Expand Up @@ -240,6 +243,9 @@ export async function configFromJobInput(): Promise<Config> {
let externalDataJsonPath: undefined | string = core.getInput('external-data-json-path');
const maxItemsInChart = getUintInput('max-items-in-chart');
let failThreshold = getPercentageInput('fail-threshold');
const commitMessage: string | undefined = core.getInput('commit-message') || undefined;
const commitUserName: string | undefined = core.getInput('commit-user-name') || undefined;
const commitUserEmail: string | undefined = core.getInput('commit-user-name') || undefined;

validateToolType(tool);
outputFilePath = await validateOutputFilePath(outputFilePath);
Expand Down Expand Up @@ -287,5 +293,8 @@ export async function configFromJobInput(): Promise<Config> {
maxItemsInChart,
failThreshold,
ref,
commitMessage,
commitUserName,
commitUserEmail,
};
}
27 changes: 19 additions & 8 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ interface ExecResult {
code: number | null;
}

interface GitConfig {
commitUserName?: string;
commitUserEmail?: string;
}

async function capture(cmd: string, args: string[]): Promise<ExecResult> {
const res: ExecResult = {
stdout: '',
Expand Down Expand Up @@ -54,15 +59,15 @@ export function getServerName(repositoryUrl: string | undefined): string {
return getServerUrlObj(repositoryUrl).hostname;
}

export async function cmd(additionalGitOptions: string[], ...args: string[]): Promise<string> {
export async function cmd(config: GitConfig, additionalGitOptions: string[], ...args: string[]): Promise<string> {
core.debug(`Executing Git: ${args.join(' ')}`);
const serverUrl = getServerUrl(github.context.payload.repository?.html_url);
const userArgs = [
...additionalGitOptions,
'-c',
'user.name=github-action-benchmark',
`user.name=${config.commitUserName ?? 'github-action-benchmark'}`,
'-c',
'[email protected]',
`user.email=${config.commitUserEmail ?? '[email protected]'}`,
'-c',
`http.${serverUrl}/.extraheader=`, // This config is necessary to support actions/checkout@v2 (#9)
];
Expand All @@ -84,6 +89,7 @@ function getRepoRemoteUrl(token: string, repoUrl: string): string {
}

export async function push(
config: GitConfig,
token: string,
repoUrl: string | undefined,
branch: string,
Expand All @@ -98,10 +104,11 @@ export async function push(
args = args.concat(options);
}

return cmd(additionalGitOptions, ...args);
return cmd(config, additionalGitOptions, ...args);
}

export async function pull(
config: GitConfig,
token: string | undefined,
branch: string,
additionalGitOptions: string[] = [],
Expand All @@ -115,10 +122,11 @@ export async function pull(
args = args.concat(options);
}

return cmd(additionalGitOptions, ...args);
return cmd(config, additionalGitOptions, ...args);
}

export async function fetch(
config: GitConfig,
token: string | undefined,
branch: string,
additionalGitOptions: string[] = [],
Expand All @@ -132,10 +140,11 @@ export async function fetch(
args = args.concat(options);
}

return cmd(additionalGitOptions, ...args);
return cmd(config, additionalGitOptions, ...args);
}

export async function clone(
config: GitConfig,
token: string,
ghRepository: string,
baseDirectory: string,
Expand All @@ -150,9 +159,11 @@ export async function clone(
args = args.concat(options);
}

return cmd(additionalGitOptions, ...args);
return cmd(config, additionalGitOptions, ...args);
}

export async function checkout(
config: GitConfig,
ghRef: string,
additionalGitOptions: string[] = [],
...options: string[]
Expand All @@ -164,5 +175,5 @@ export async function checkout(
args = args.concat(options);
}

return cmd(additionalGitOptions, ...args);
return cmd(config, additionalGitOptions, ...args);
}
28 changes: 15 additions & 13 deletions src/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async function storeDataJs(dataPath: string, data: DataJson) {
core.debug(`Overwrote ${dataPath} for adding new data`);
}

async function addIndexHtmlIfNeeded(additionalGitArguments: string[], dir: string, baseDir: string) {
async function addIndexHtmlIfNeeded(config: Config, additionalGitArguments: string[], dir: string, baseDir: string) {
const indexHtmlRelativePath = path.join(dir, 'index.html');
const indexHtmlFullPath = path.join(baseDir, indexHtmlRelativePath);
try {
Expand All @@ -55,7 +55,7 @@ async function addIndexHtmlIfNeeded(additionalGitArguments: string[], dir: strin
}

await fs.writeFile(indexHtmlFullPath, DEFAULT_INDEX_HTML, 'utf8');
await git.cmd(additionalGitArguments, 'add', indexHtmlRelativePath);
await git.cmd(config, additionalGitArguments, 'add', indexHtmlRelativePath);
console.log('Created default index.html at', indexHtmlFullPath);
}

Expand Down Expand Up @@ -389,14 +389,14 @@ async function writeBenchmarkToGitHubPagesWithRetry(

if (githubToken && !skipFetchGhPages && ghRepository) {
benchmarkBaseDir = './benchmark-data-repository';
await git.clone(githubToken, ghRepository, benchmarkBaseDir);
await git.clone(config, githubToken, ghRepository, benchmarkBaseDir);
rollbackActions.push(async () => {
await io.rmRF(benchmarkBaseDir);
});
extraGitArguments = [`--work-tree=${benchmarkBaseDir}`, `--git-dir=${benchmarkBaseDir}/.git`];
await git.checkout(ghPagesBranch, extraGitArguments);
await git.checkout(config, ghPagesBranch, extraGitArguments);
} else if (!skipFetchGhPages && (!isPrivateRepo || githubToken)) {
await git.pull(githubToken, ghPagesBranch);
await git.pull(config, githubToken, ghPagesBranch);
} else if (isPrivateRepo && !skipFetchGhPages) {
core.warning(
"'git pull' was skipped. If you want to ensure GitHub Pages branch is up-to-date " +
Expand Down Expand Up @@ -425,13 +425,15 @@ async function writeBenchmarkToGitHubPagesWithRetry(

await storeDataJs(dataPath, data);

await git.cmd(extraGitArguments, 'add', path.join(benchmarkDataRelativeDirPath, 'data.js'));
await addIndexHtmlIfNeeded(extraGitArguments, benchmarkDataRelativeDirPath, benchmarkBaseDir);
await git.cmd(extraGitArguments, 'commit', '-m', `add ${name} (${tool}) benchmark result for ${bench.commit.id}`);
await git.cmd(config, extraGitArguments, 'add', path.join(benchmarkDataRelativeDirPath, 'data.js'));
await addIndexHtmlIfNeeded(config, extraGitArguments, benchmarkDataRelativeDirPath, benchmarkBaseDir);

const commitMessage = config.commitMessage ?? `add ${name} (${tool}) benchmark result for ${bench.commit.id}`;
await git.cmd(config, extraGitArguments, 'commit', '-m', commitMessage);

if (githubToken && autoPush) {
try {
await git.push(githubToken, ghRepository, ghPagesBranch, extraGitArguments);
await git.push(config, githubToken, ghRepository, ghPagesBranch, extraGitArguments);
console.log(
`Automatically pushed the generated commit to ${ghPagesBranch} branch since 'auto-push' is set to true`,
);
Expand All @@ -445,7 +447,7 @@ async function writeBenchmarkToGitHubPagesWithRetry(

if (retry > 0) {
core.debug('Rollback the auto-generated commit before retry');
await git.cmd(extraGitArguments, 'reset', '--hard', 'HEAD~1');
await git.cmd(config, extraGitArguments, 'reset', '--hard', 'HEAD~1');

// we need to rollback actions in order so not running them concurrently
for (const action of rollbackActions) {
Expand Down Expand Up @@ -476,16 +478,16 @@ async function writeBenchmarkToGitHubPages(bench: Benchmark, config: Config): Pr
const { ghPagesBranch, skipFetchGhPages, ghRepository, githubToken } = config;
if (!ghRepository) {
if (!skipFetchGhPages) {
await git.fetch(githubToken, ghPagesBranch);
await git.fetch(config, githubToken, ghPagesBranch);
}
await git.cmd([], 'switch', ghPagesBranch);
await git.cmd(config, [], 'switch', ghPagesBranch);
}
try {
return await writeBenchmarkToGitHubPagesWithRetry(bench, config, 10);
} finally {
if (!ghRepository) {
// `git switch` does not work for backing to detached head
await git.cmd([], 'checkout', '-');
await git.cmd(config, [], 'checkout', '-');
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions test/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ describe('configFromJobInput()', function () {
});

it('resolves home directory in output directory path', async function () {
if (os.platform() === 'win32') {
// Home directory is not supported on Windows
return;
}
const home = os.homedir();
const absCwd = process.cwd();
if (!absCwd.startsWith(home)) {
Expand Down
Loading

0 comments on commit 785538a

Please sign in to comment.