diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..2bbb172 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,24 @@ +name: Check Formatting + +on: + pull_request: + branches: + - main + +jobs: + check-format: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set Node.js 18.x + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install + run: yarn --frozen-lockfile + + - name: Check formatting with Prettier + run: npx prettier --check . diff --git a/.husky/pre-commit b/.husky/pre-commit index 8e0da16..9458057 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -4,4 +4,3 @@ npx --no-install lint-staged --allow-empty node tools/pre-commit.js - diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..0b8ea3e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +node_modules +dist +/yarn.lock +/.vscode +/.idea +/.github +/.husky +/.yarn +/.env diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5b50b39 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "endOfLine": "lf", + "tabWidth": 2 +} diff --git a/README.md b/README.md index 8ef4964..a86b4cf 100644 --- a/README.md +++ b/README.md @@ -76,37 +76,37 @@ jobs: # Common names for this branch include main and master. # # Default: main - main-branch-name: "" + main-branch-name: '' # Applies the derived SHAs for base and head as NX_BASE and NX_HEAD environment variables within the current Job. # # Default: true - set-environment-variables-for-job: "" + set-environment-variables-for-job: '' # By default, if no successful workflow run is found on the main branch to determine the SHA, we will log a warning and use HEAD~1. Enable this option to error and exit instead. # # Default: false - error-on-no-successful-workflow: "" + error-on-no-successful-workflow: '' # Fallback SHA to use if no successful workflow run is found. This can be useful in scenarios where you need a specific commit as a reference for comparison, especially in newly set up repositories or those with sparse workflow runs. # # Default: "" - fallback-sha: "" + fallback-sha: '' # The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc. # # Default: push - last-successful-event: "" + last-successful-event: '' # The path where your repository is. This is only required for cases where the repository code is checked out or moved to a specific path. # # Default: . - working-directory: "" + working-directory: '' # The ID of the github action workflow to check for successful run or the name of the file name containing the workflow. # E.g. 'ci.yml'. If not provided, current workflow id will be used # - workflow-id: "" + workflow-id: '' ``` @@ -123,8 +123,8 @@ jobs: runs-on: ubuntu-latest name: My Job permissions: - contents: "read" - actions: "read" + contents: 'read' + actions: 'read' ``` diff --git a/action.yml b/action.yml index 1bfdd97..2d10fc5 100644 --- a/action.yml +++ b/action.yml @@ -1,28 +1,28 @@ -name: "Nx set SHAs" -description: "Derives SHAs for base and head for use in nx affected commands, optionally setting them as env variables for the current job" +name: 'Nx set SHAs' +description: 'Derives SHAs for base and head for use in nx affected commands, optionally setting them as env variables for the current job' inputs: main-branch-name: - description: "The name of the main branch in your repo, used as the target of PRs. E.g. main, master etc" - default: "main" + description: 'The name of the main branch in your repo, used as the target of PRs. E.g. main, master etc' + default: 'main' set-environment-variables-for-job: - description: "Applies the derived SHAs for base and head as NX_BASE and NX_HEAD environment variables within the current Job" - default: "true" + description: 'Applies the derived SHAs for base and head as NX_BASE and NX_HEAD environment variables within the current Job' + default: 'true' error-on-no-successful-workflow: - description: "By default, if no successful workflow is found on the main branch to determine the SHA, we will log a warning and use HEAD~1. Enable this option to error and exit instead." - default: "false" + description: 'By default, if no successful workflow is found on the main branch to determine the SHA, we will log a warning and use HEAD~1. Enable this option to error and exit instead.' + default: 'false' fallback-sha: - description: "Fallback SHA to use if no successful workflow run is found." + description: 'Fallback SHA to use if no successful workflow run is found.' required: false - default: "" + default: '' last-successful-event: - description: "The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc" - default: "push" + description: 'The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc' + default: 'push' working-directory: - description: "The directory where your repository is located" - default: "." + description: 'The directory where your repository is located' + default: '.' workflow-id: - description: "The ID of the workflow to track or name of the file name. E.g. ci.yml. Defaults to current workflow" + description: 'The ID of the workflow to track or name of the file name. E.g. ci.yml. Defaults to current workflow' outputs: base: @@ -36,7 +36,7 @@ outputs: value: ${{ steps.setSHAs.outputs.noPreviousBuild }} runs: - using: "composite" + using: 'composite' steps: - name: Set base and head SHAs used for nx affected id: setSHAs @@ -68,5 +68,5 @@ runs: echo "NX_HEAD=${{ steps.setSHAs.outputs.head }}" >> $GITHUB_ENV echo "NX_BASE and NX_HEAD environment variables have been set for the current Job" branding: - icon: "terminal" - color: "blue" + icon: 'terminal' + color: 'blue' diff --git a/dist/index.js b/dist/index.js index 7d60c65..01d3178 100644 --- a/dist/index.js +++ b/dist/index.js @@ -37868,7 +37868,7 @@ const lastSuccessfulEvent = process.argv[5]; const workingDirectory = process.argv[6]; const workflowId = process.argv[7]; const fallbackSHA = process.argv[8]; -const defaultWorkingDirectory = "."; +const defaultWorkingDirectory = '.'; const ProxifiedClient = action_1.Octokit.plugin(proxyPlugin); let BASE_SHA; (() => __awaiter(void 0, void 0, void 0, function* () { @@ -37877,20 +37877,20 @@ let BASE_SHA; process.chdir(workingDirectory); } else { - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`); } } - const headResult = (0, child_process_1.spawnSync)("git", ["rev-parse", "HEAD"], { - encoding: "utf-8", + const headResult = (0, child_process_1.spawnSync)('git', ['rev-parse', 'HEAD'], { + encoding: 'utf-8', }); const HEAD_SHA = headResult.stdout; - if ((["pull_request", "pull_request_target"].includes(eventName) && + if ((['pull_request', 'pull_request_target'].includes(eventName) && !github.context.payload.pull_request.merged) || - eventName == "merge_group") { + eventName == 'merge_group') { try { const mergeBaseRef = yield findMergeBaseRef(); - const baseResult = (0, child_process_1.spawnSync)("git", ["merge-base", `origin/${mainBranchName}`, mergeBaseRef], { encoding: "utf-8" }); + const baseResult = (0, child_process_1.spawnSync)('git', ['merge-base', `origin/${mainBranchName}`, mergeBaseRef], { encoding: 'utf-8' }); BASE_SHA = baseResult.stdout; } catch (e) { @@ -37907,12 +37907,12 @@ let BASE_SHA; return; } if (!BASE_SHA) { - if (errorOnNoSuccessfulWorkflow === "true") { + if (errorOnNoSuccessfulWorkflow === 'true') { reportFailure(mainBranchName); return; } else { - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}', or the latest successful workflow was connected to a commit which no longer exists on that branch (e.g. if that branch was rebased)\n`); if (fallbackSHA) { BASE_SHA = fallbackSHA; @@ -37920,28 +37920,28 @@ let BASE_SHA; } else { process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`); - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`); - process.stdout.write("\n"); - const commitCountOutput = (0, child_process_1.spawnSync)("git", ["rev-list", "--count", `origin/${mainBranchName}`], { encoding: "utf-8" }).stdout; + process.stdout.write('\n'); + const commitCountOutput = (0, child_process_1.spawnSync)('git', ['rev-list', '--count', `origin/${mainBranchName}`], { encoding: 'utf-8' }).stdout; const commitCount = parseInt(stripNewLineEndings(commitCountOutput), 10); - const LAST_COMMIT_CMD = `origin/${mainBranchName}${commitCount > 1 ? "~1" : ""}`; - const baseRes = (0, child_process_1.spawnSync)("git", ["rev-parse", LAST_COMMIT_CMD], { - encoding: "utf-8", + const LAST_COMMIT_CMD = `origin/${mainBranchName}${commitCount > 1 ? '~1' : ''}`; + const baseRes = (0, child_process_1.spawnSync)('git', ['rev-parse', LAST_COMMIT_CMD], { + encoding: 'utf-8', }); BASE_SHA = baseRes.stdout; } - core.setOutput("noPreviousBuild", "true"); + core.setOutput('noPreviousBuild', 'true'); } } else { - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`Found the last successful workflow run on 'origin/${mainBranchName}'\n`); process.stdout.write(`Commit: ${BASE_SHA}\n`); } } - core.setOutput("base", stripNewLineEndings(BASE_SHA)); - core.setOutput("head", stripNewLineEndings(HEAD_SHA)); + core.setOutput('base', stripNewLineEndings(BASE_SHA)); + core.setOutput('head', stripNewLineEndings(HEAD_SHA)); }))(); function reportFailure(branchName) { core.setFailed(` @@ -37953,7 +37953,7 @@ function reportFailure(branchName) { - If no, then you might have changed your git history and those commits no longer exist.`); } function proxyPlugin(octokit) { - octokit.hook.before("request", (options) => { + octokit.hook.before('request', (options) => { const proxy = (0, proxy_from_env_1.getProxyForUrl)(options.baseUrl); if (proxy) { options.request.agent = new https_proxy_agent_1.HttpsProxyAgent(proxy); @@ -37975,7 +37975,7 @@ function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, lastSucc run_id, }) .then(({ data: { workflow_id } }) => workflow_id); - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`Workflow Id not provided. Using workflow '${workflow_id}'\n`); } // fetch all workflow runs on a given repo/branch/workflow with push and success @@ -37984,13 +37984,13 @@ function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, lastSucc owner, repo, // on some workflow runs we do not have branch property - branch: lastSuccessfulEvent === "push" || - lastSuccessfulEvent === "workflow_dispatch" + branch: lastSuccessfulEvent === 'push' || + lastSuccessfulEvent === 'workflow_dispatch' ? branch : undefined, workflow_id, event: lastSuccessfulEvent, - status: "success", + status: 'success', }) .then(({ data: { workflow_runs } }) => workflow_runs.map((run) => run.head_sha)); return yield findExistingCommit(octokit, branch, shas); @@ -37998,12 +37998,12 @@ function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, lastSucc } function findMergeBaseRef() { return __awaiter(this, void 0, void 0, function* () { - if (eventName == "merge_group") { + if (eventName == 'merge_group') { const mergeQueueBranch = yield findMergeQueueBranch(); return `origin/${mergeQueueBranch}`; } else { - return "HEAD"; + return 'HEAD'; } }); } @@ -38016,9 +38016,9 @@ function findMergeQueueBranch() { return __awaiter(this, void 0, void 0, function* () { const pull_number = findMergeQueuePr(); if (!pull_number) { - throw new Error("Failed to determine PR number"); + throw new Error('Failed to determine PR number'); } - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`Found PR #${pull_number} from merge queue branch\n`); const octokit = new ProxifiedClient(); const result = yield octokit.request(`GET /repos/${owner}/${repo}/pulls/${pull_number}`, { owner, repo, pull_number: +pull_number }); @@ -38044,17 +38044,17 @@ function findExistingCommit(octokit, branchName, shas) { function commitExists(octokit, branchName, commitSha) { return __awaiter(this, void 0, void 0, function* () { try { - (0, child_process_1.spawnSync)("git", ["cat-file", "-e", commitSha], { - stdio: ["pipe", "pipe", null], + (0, child_process_1.spawnSync)('git', ['cat-file', '-e', commitSha], { + stdio: ['pipe', 'pipe', null], }); // Check the commit exists in general - yield octokit.request("GET /repos/{owner}/{repo}/commits/{commit_sha}", { + yield octokit.request('GET /repos/{owner}/{repo}/commits/{commit_sha}', { owner, repo, commit_sha: commitSha, }); // Check the commit exists on the expected main branch (it will not in the case of a rebased main branch) - const commits = yield octokit.request("GET /repos/{owner}/{repo}/commits", { + const commits = yield octokit.request('GET /repos/{owner}/{repo}/commits', { owner, repo, sha: branchName, @@ -38071,7 +38071,7 @@ function commitExists(octokit, branchName, commitSha) { * Strips LF line endings from given string */ function stripNewLineEndings(string) { - return string.replace("\n", ""); + return string.replace('\n', ''); } diff --git a/find-successful-workflow.ts b/find-successful-workflow.ts index 0504758..c2c1324 100644 --- a/find-successful-workflow.ts +++ b/find-successful-workflow.ts @@ -1,10 +1,10 @@ -import * as core from "@actions/core"; -import * as github from "@actions/github"; -import { Octokit } from "@octokit/action"; -import { spawnSync } from "child_process"; -import { existsSync } from "fs"; -import { HttpsProxyAgent } from "https-proxy-agent"; -import { getProxyForUrl } from "proxy-from-env"; +import * as core from '@actions/core'; +import * as github from '@actions/github'; +import { Octokit } from '@octokit/action'; +import { spawnSync } from 'child_process'; +import { existsSync } from 'fs'; +import { HttpsProxyAgent } from 'https-proxy-agent'; +import { getProxyForUrl } from 'proxy-from-env'; const { runId, @@ -18,7 +18,7 @@ const lastSuccessfulEvent = process.argv[5]; const workingDirectory = process.argv[6]; const workflowId = process.argv[7]; const fallbackSHA = process.argv[8]; -const defaultWorkingDirectory = "."; +const defaultWorkingDirectory = '.'; const ProxifiedClient = Octokit.plugin(proxyPlugin); @@ -28,29 +28,29 @@ let BASE_SHA: string; if (existsSync(workingDirectory)) { process.chdir(workingDirectory); } else { - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write( `WARNING: Working directory '${workingDirectory}' doesn't exist.\n`, ); } } - const headResult = spawnSync("git", ["rev-parse", "HEAD"], { - encoding: "utf-8", + const headResult = spawnSync('git', ['rev-parse', 'HEAD'], { + encoding: 'utf-8', }); const HEAD_SHA = headResult.stdout; if ( - (["pull_request", "pull_request_target"].includes(eventName) && + (['pull_request', 'pull_request_target'].includes(eventName) && !github.context.payload.pull_request.merged) || - eventName == "merge_group" + eventName == 'merge_group' ) { try { const mergeBaseRef = await findMergeBaseRef(); const baseResult = spawnSync( - "git", - ["merge-base", `origin/${mainBranchName}`, mergeBaseRef], - { encoding: "utf-8" }, + 'git', + ['merge-base', `origin/${mainBranchName}`, mergeBaseRef], + { encoding: 'utf-8' }, ); BASE_SHA = baseResult.stdout; } catch (e) { @@ -73,11 +73,11 @@ let BASE_SHA: string; } if (!BASE_SHA) { - if (errorOnNoSuccessfulWorkflow === "true") { + if (errorOnNoSuccessfulWorkflow === 'true') { reportFailure(mainBranchName); return; } else { - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write( `WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}', or the latest successful workflow was connected to a commit which no longer exists on that branch (e.g. if that branch was rebased)\n`, ); @@ -88,16 +88,16 @@ let BASE_SHA: string; process.stdout.write( `We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`, ); - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write( `NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`, ); - process.stdout.write("\n"); + process.stdout.write('\n'); const commitCountOutput = spawnSync( - "git", - ["rev-list", "--count", `origin/${mainBranchName}`], - { encoding: "utf-8" }, + 'git', + ['rev-list', '--count', `origin/${mainBranchName}`], + { encoding: 'utf-8' }, ).stdout; const commitCount = parseInt( stripNewLineEndings(commitCountOutput), @@ -105,25 +105,25 @@ let BASE_SHA: string; ); const LAST_COMMIT_CMD = `origin/${mainBranchName}${ - commitCount > 1 ? "~1" : "" + commitCount > 1 ? '~1' : '' }`; - const baseRes = spawnSync("git", ["rev-parse", LAST_COMMIT_CMD], { - encoding: "utf-8", + const baseRes = spawnSync('git', ['rev-parse', LAST_COMMIT_CMD], { + encoding: 'utf-8', }); BASE_SHA = baseRes.stdout; } - core.setOutput("noPreviousBuild", "true"); + core.setOutput('noPreviousBuild', 'true'); } } else { - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write( `Found the last successful workflow run on 'origin/${mainBranchName}'\n`, ); process.stdout.write(`Commit: ${BASE_SHA}\n`); } } - core.setOutput("base", stripNewLineEndings(BASE_SHA)); - core.setOutput("head", stripNewLineEndings(HEAD_SHA)); + core.setOutput('base', stripNewLineEndings(BASE_SHA)); + core.setOutput('head', stripNewLineEndings(HEAD_SHA)); })(); function reportFailure(branchName: string): void { @@ -137,7 +137,7 @@ function reportFailure(branchName: string): void { } function proxyPlugin(octokit: Octokit): void { - octokit.hook.before("request", (options) => { + octokit.hook.before('request', (options) => { const proxy: URL = getProxyForUrl(options.baseUrl); if (proxy) { options.request.agent = new HttpsProxyAgent(proxy); @@ -166,7 +166,7 @@ async function findSuccessfulCommit( run_id, }) .then(({ data: { workflow_id } }) => workflow_id); - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write( `Workflow Id not provided. Using workflow '${workflow_id}'\n`, ); @@ -180,13 +180,13 @@ async function findSuccessfulCommit( repo, // on some workflow runs we do not have branch property branch: - lastSuccessfulEvent === "push" || - lastSuccessfulEvent === "workflow_dispatch" + lastSuccessfulEvent === 'push' || + lastSuccessfulEvent === 'workflow_dispatch' ? branch : undefined, workflow_id, event: lastSuccessfulEvent, - status: "success", + status: 'success', }, ) .then(({ data: { workflow_runs } }) => @@ -197,11 +197,11 @@ async function findSuccessfulCommit( } async function findMergeBaseRef(): Promise { - if (eventName == "merge_group") { + if (eventName == 'merge_group') { const mergeQueueBranch = await findMergeQueueBranch(); return `origin/${mergeQueueBranch}`; } else { - return "HEAD"; + return 'HEAD'; } } @@ -216,9 +216,9 @@ function findMergeQueuePr(): string { async function findMergeQueueBranch(): Promise { const pull_number = findMergeQueuePr(); if (!pull_number) { - throw new Error("Failed to determine PR number"); + throw new Error('Failed to determine PR number'); } - process.stdout.write("\n"); + process.stdout.write('\n'); process.stdout.write(`Found PR #${pull_number} from merge queue branch\n`); const octokit = new ProxifiedClient(); const result = await octokit.request( @@ -253,19 +253,19 @@ async function commitExists( commitSha: string, ): Promise { try { - spawnSync("git", ["cat-file", "-e", commitSha], { - stdio: ["pipe", "pipe", null], + spawnSync('git', ['cat-file', '-e', commitSha], { + stdio: ['pipe', 'pipe', null], }); // Check the commit exists in general - await octokit.request("GET /repos/{owner}/{repo}/commits/{commit_sha}", { + await octokit.request('GET /repos/{owner}/{repo}/commits/{commit_sha}', { owner, repo, commit_sha: commitSha, }); // Check the commit exists on the expected main branch (it will not in the case of a rebased main branch) - const commits = await octokit.request("GET /repos/{owner}/{repo}/commits", { + const commits = await octokit.request('GET /repos/{owner}/{repo}/commits', { owner, repo, sha: branchName, @@ -284,5 +284,5 @@ async function commitExists( * Strips LF line endings from given string */ function stripNewLineEndings(string: string): string { - return string.replace("\n", ""); + return string.replace('\n', ''); } diff --git a/package.json b/package.json index bb7f2fc..7412322 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "description": "This package.json is here purely to control the version of the Action, in combination with https://github.com/JamesHenry/publish-shell-action", "scripts": { "build": "ncc build find-successful-workflow.ts --license licenses.txt", - "prepare": "is-ci || husky install" + "prepare": "is-ci || husky install", + "format:check": "prettier --check .", + "format": "prettier --write ." }, "bugs": { "url": "https://github.com/nrwl/nx-set-shas/issues" diff --git a/tools/pre-commit.js b/tools/pre-commit.js index bef6740..d916152 100644 --- a/tools/pre-commit.js +++ b/tools/pre-commit.js @@ -12,27 +12,23 @@ function printErrorAndExit(error) { console.log(`\n${chalk.bgGreen.bold(' Validating commit ')}\n`); console.log(` > Checking the build`); try { - execSync(`npm run build`, - { - stdio: ['pipe', 'pipe', 'pipe'], - env: { - ...process.env, - FORCE_COLOR: 'true', - }, - } - ); + execSync(`npm run build`, { + stdio: ['pipe', 'pipe', 'pipe'], + env: { + ...process.env, + FORCE_COLOR: 'true', + }, + }); console.log(` ✔ Build successful`); - const result = execSync(`git diff --name-only`, - { - stdio: ['pipe', 'pipe', 'pipe'], - encoding: 'utf-8', - env: { - ...process.env, - FORCE_COLOR: 'true', - }, - } - ); - const changedFiles = result.split('\n').filter(f => f.startsWith('dist/')); + const result = execSync(`git diff --name-only`, { + stdio: ['pipe', 'pipe', 'pipe'], + encoding: 'utf-8', + env: { + ...process.env, + FORCE_COLOR: 'true', + }, + }); + const changedFiles = result.split('\n').filter((f) => f.startsWith('dist/')); if (changedFiles.length > 0) { console.log(` > Adding modified build files`); changedFiles.forEach((f) => { @@ -40,12 +36,22 @@ try { stdio: ['pipe', 'pipe', 'pipe'], }); }); - console.log(` ✔ Commit expanded with ${changedFiles.length} changed file(s)`); + console.log( + ` ✔ Commit expanded with ${changedFiles.length} changed file(s)`, + ); } + execSync(`npm run format`, { + stdio: ['pipe', 'pipe', 'pipe'], + env: { + ...process.env, + FORCE_COLOR: 'true', + }, + }); + console.log(` ✔ Formatted files`); + console.log(`\n${chalk.bold(' Commit successful ')}\n`); process.exit(0); - } catch (error) { printErrorAndExit(error); } diff --git a/tsconfig.json b/tsconfig.json index 5282f64..ade24d7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,6 @@ "target": "es2015", "module": "commonjs", "moduleResolution": "node", - "types": ["node"], + "types": ["node"] } -} \ No newline at end of file +}