diff --git a/README.md b/README.md index 023b4d2..dfbb1ed 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ [![Check dist/](https://github.com/actions/typescript-action/actions/workflows/check-dist.yml/badge.svg)](https://github.com/actions/typescript-action/actions/workflows/check-dist.yml) [![CodeQL](https://github.com/actions/typescript-action/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/actions/typescript-action/actions/workflows/codeql-analysis.yml) -Souji Action deletes all GitHub Actions Caches created for branches related to -the context of the triggered workflow event. +Souji Action is a GitHub Action that deletes all GitHub Actions Caches related +to the context of the triggered workflow event, without any configuration +required. ## Usage @@ -32,5 +33,4 @@ jobs: For instance, when a Pull Request created in the branch `feat/awesome-feature` is "merged" or "closed," a workflow event is triggered and the workflow is executed. At this time, all GitHub Actions Caches created under the merge ref -`refs/pull/{pull_request_number}/merge` and the head ref -`refs/heads/feat/awesome-feature` are deleted. +`refs/pull/{pull_request_number}/merge` are deleted. diff --git a/dist/index.js b/dist/index.js index 733c8a2..9d82c97 100644 --- a/dist/index.js +++ b/dist/index.js @@ -29618,6 +29618,33 @@ function wrappy (fn, cb) { } +/***/ }), + +/***/ 1356: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.convertRef = void 0; +exports.convertRef = ((str, { refType }) => { + if (str === null || str === undefined) + return null; + if (str.startsWith('refs/')) + return str; + switch (refType) { + case 'branch': + return `refs/heads/${str}`; + case 'tag': + return `refs/tags/${str}`; + case 'pull': + return `refs/pull/${str}/merge`; + default: + return null; + } +}); + + /***/ }), /***/ 9356: @@ -29652,8 +29679,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.run = void 0; const core = __importStar(__nccwpck_require__(9093)); const github = __importStar(__nccwpck_require__(5942)); -const v = __importStar(__nccwpck_require__(6661)); -const OptionalStringSchema = v.optional(v.string()); +const ref_1 = __nccwpck_require__(2636); const deleteRefActionsCache = async (octokit, repo, ref) => { // Get the list of cache IDs // https://github.com/octokit/plugin-paginate-rest.js#octokitpaginate @@ -29682,40 +29708,138 @@ async function run() { const token = core.getInput('repo-token'); const octokit = github.getOctokit(token); // get repostiory information - const { repo } = github.context; - // MEMO: payloadから取得できるのは確認したけど、型何もついてない - const payload = github.context.payload; - const prNumber = payload.pull_request?.number; - const headRef = v.parse(OptionalStringSchema, payload.pull_request?.head?.ref); - const ref = v.parse(OptionalStringSchema, payload.ref); - if (prNumber) { - // fire when event is pull_request or pull_request_target or pull_request_review or pull_request_review_comment - core.info(`delete cache for refs/pull/${prNumber}/merge`); - await deleteRefActionsCache(octokit, repo, `refs/pull/${prNumber}/merge`); - core.info('done ✅'); - } - if (headRef) { - // fire when event is pull_request or pull_request_target or pull_request_review or pull_request_review_comment - core.info(`delete cache for refs/heads/${headRef}`); - await deleteRefActionsCache(octokit, repo, `refs/heads/${headRef}`); - core.info('done ✅'); - } - if (ref) { - // fire when event is workflow_dispatch or push - core.info(`delete cache for ${ref}`); - await deleteRefActionsCache(octokit, repo, ref); - core.info('done ✅'); + const { repo, eventName, payload } = github.context; + const ref = (0, ref_1.getRef)({ eventName, payload }); + if (ref === null) { + core.info('Could not determine deletion target.'); + core.info('If you suspect this is a bug, please consider raising an issue to help us address it promptly.'); + return; } + core.info(`Delete cache for ${ref}`); + await deleteRefActionsCache(octokit, repo, ref); + core.info('Done ✅'); } catch (error) { // Fail the workflow run if an error occurs - if (error instanceof Error) + if (error instanceof Error) { core.setFailed(error.message); + core.info('If you suspect this is a bug, please consider raising an issue to help us address it promptly.'); + } } } exports.run = run; +/***/ }), + +/***/ 2636: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getRef = void 0; +const v = __importStar(__nccwpck_require__(6661)); +const schema_1 = __nccwpck_require__(3731); +const utils_1 = __nccwpck_require__(1356); +exports.getRef = (({ eventName, payload }) => { + switch (eventName) { + case 'check_run': + return (0, utils_1.convertRef)(v.parse(schema_1.NullableStringSchema, payload.check_run.check_suite.head_branch), { refType: 'branch' }); + case 'check_suite': + return (0, utils_1.convertRef)(v.parse(schema_1.NullableStringSchema, payload.check_suite.head_branch), { refType: 'branch' }); + case 'create': + return (0, utils_1.convertRef)(v.parse(schema_1.NullableStringSchema, payload.ref), { + refType: payload.ref_type + }); + case 'delete': + return (0, utils_1.convertRef)(v.parse(schema_1.NullableStringSchema, payload.ref), { + refType: payload.ref_type + }); + case 'deployment_status': + return (0, utils_1.convertRef)(v.parse(schema_1.OptionalStringSchema, payload.workflow_run?.head_branch), { + refType: 'branch' + }); + case 'issue_comment': + return (0, utils_1.convertRef)(v.parse(schema_1.StringSchema, payload.issue?.number.toString()), { + refType: 'pull' + }); + case 'pull_request': + return (0, utils_1.convertRef)(payload.pull_request?.number.toString(), { + refType: 'pull' + }); + case 'pull_request_review': + return (0, utils_1.convertRef)(payload.pull_request?.number.toString(), { + refType: 'pull' + }); + case 'pull_request_review_comment': + return (0, utils_1.convertRef)(payload.pull_request?.number.toString(), { + refType: 'pull' + }); + case 'pull_request_target': + return (0, utils_1.convertRef)(payload.pull_request?.number.toString(), { + refType: 'pull' + }); + case 'push': + return v.parse(schema_1.StringSchema, payload.ref); + case 'registry_package': + return (0, utils_1.convertRef)(v.parse(schema_1.OptionalStringSchema, payload.registry_package?.package_version?.release?.tag_name), { + refType: 'tag' + }); + case 'release': + return (0, utils_1.convertRef)(v.parse(schema_1.StringSchema, payload.release.tag_name), { + refType: 'tag' + }); + case 'workflow_dispatch': + return v.parse(schema_1.StringSchema, payload.ref); + case 'workflow_run': + return (0, utils_1.convertRef)(v.parse(schema_1.NullableStringSchema, payload.workflow_run.head_branch), { + refType: 'branch' + }); + default: + throw new Error(`${eventName} event is not supported.`); + } +}); + + +/***/ }), + +/***/ 3731: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.NullableStringSchema = exports.OptionalStringSchema = exports.StringSchema = void 0; +const valibot_1 = __nccwpck_require__(6661); +exports.StringSchema = (0, valibot_1.string)(); +exports.OptionalStringSchema = (0, valibot_1.optional)((0, valibot_1.string)()); +exports.NullableStringSchema = (0, valibot_1.nullable)((0, valibot_1.string)()); + + /***/ }), /***/ 9491: diff --git a/src/internal/utils.ts b/src/internal/utils.ts new file mode 100644 index 0000000..ffbd844 --- /dev/null +++ b/src/internal/utils.ts @@ -0,0 +1,17 @@ +export const convertRef = ((str, { refType }) => { + if (str === null || str === undefined) return null + if (str.startsWith('refs/')) return str + switch (refType) { + case 'branch': + return `refs/heads/${str}` + case 'tag': + return `refs/tags/${str}` + case 'pull': + return `refs/pull/${str}/merge` + default: + return null + } +}) satisfies ( + str: string | undefined | null, + { refType }: { refType: 'branch' | 'tag' | 'pull' } +) => string | null diff --git a/src/main.ts b/src/main.ts index d7c2faa..4774734 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,6 @@ import * as core from '@actions/core' import * as github from '@actions/github' -import * as v from 'valibot' - -const OptionalStringSchema = v.optional(v.string()) +import { getRef } from './ref' const deleteRefActionsCache = async ( octokit: ReturnType, @@ -41,37 +39,27 @@ export async function run(): Promise { const octokit = github.getOctokit(token) // get repostiory information - const { repo } = github.context + const { repo, eventName, payload } = github.context - // MEMO: payloadから取得できるのは確認したけど、型何もついてない - const payload = github.context.payload - const prNumber = payload.pull_request?.number - const headRef = v.parse( - OptionalStringSchema, - payload.pull_request?.head?.ref - ) - const ref = v.parse(OptionalStringSchema, payload.ref) + const ref = getRef({ eventName, payload }) - if (prNumber) { - // fire when event is pull_request or pull_request_target or pull_request_review or pull_request_review_comment - core.info(`delete cache for refs/pull/${prNumber}/merge`) - await deleteRefActionsCache(octokit, repo, `refs/pull/${prNumber}/merge`) - core.info('done ✅') - } - if (headRef) { - // fire when event is pull_request or pull_request_target or pull_request_review or pull_request_review_comment - core.info(`delete cache for refs/heads/${headRef}`) - await deleteRefActionsCache(octokit, repo, `refs/heads/${headRef}`) - core.info('done ✅') - } - if (ref) { - // fire when event is workflow_dispatch or push - core.info(`delete cache for ${ref}`) - await deleteRefActionsCache(octokit, repo, ref) - core.info('done ✅') + if (ref === null) { + core.info('Could not determine deletion target.') + core.info( + 'If you suspect this is a bug, please consider raising an issue to help us address it promptly.' + ) + return } + core.info(`Delete cache for ${ref}`) + await deleteRefActionsCache(octokit, repo, ref) + core.info('Done ✅') } catch (error) { // Fail the workflow run if an error occurs - if (error instanceof Error) core.setFailed(error.message) + if (error instanceof Error) { + core.setFailed(error.message) + core.info( + 'If you suspect this is a bug, please consider raising an issue to help us address it promptly.' + ) + } } } diff --git a/src/ref.ts b/src/ref.ts new file mode 100644 index 0000000..5fbc163 --- /dev/null +++ b/src/ref.ts @@ -0,0 +1,97 @@ +import * as v from 'valibot' +import { WebhookPayload } from '@actions/github/lib/interfaces' +import { + OptionalStringSchema, + NullableStringSchema, + StringSchema +} from './schema' +import { convertRef } from './internal/utils' + +export const getRef = (({ eventName, payload }) => { + switch (eventName) { + case 'check_run': + return convertRef( + v.parse( + NullableStringSchema, + payload.check_run.check_suite.head_branch + ), + { refType: 'branch' } + ) + case 'check_suite': + return convertRef( + v.parse(NullableStringSchema, payload.check_suite.head_branch), + { refType: 'branch' } + ) + case 'create': + return convertRef(v.parse(NullableStringSchema, payload.ref), { + refType: payload.ref_type + }) + case 'delete': + return convertRef(v.parse(NullableStringSchema, payload.ref), { + refType: payload.ref_type + }) + case 'deployment_status': + return convertRef( + v.parse(OptionalStringSchema, payload.workflow_run?.head_branch), + { + refType: 'branch' + } + ) + case 'issue_comment': + return convertRef( + v.parse(StringSchema, payload.issue?.number.toString()), + { + refType: 'pull' + } + ) + case 'pull_request': + return convertRef(payload.pull_request?.number.toString(), { + refType: 'pull' + }) + case 'pull_request_review': + return convertRef(payload.pull_request?.number.toString(), { + refType: 'pull' + }) + case 'pull_request_review_comment': + return convertRef(payload.pull_request?.number.toString(), { + refType: 'pull' + }) + case 'pull_request_target': + return convertRef(payload.pull_request?.number.toString(), { + refType: 'pull' + }) + case 'push': + return v.parse(StringSchema, payload.ref) + case 'registry_package': + return convertRef( + v.parse( + OptionalStringSchema, + payload.registry_package?.package_version?.release?.tag_name + ), + { + refType: 'tag' + } + ) + case 'release': + return convertRef(v.parse(StringSchema, payload.release.tag_name), { + refType: 'tag' + }) + case 'workflow_dispatch': + return v.parse(StringSchema, payload.ref) + case 'workflow_run': + return convertRef( + v.parse(NullableStringSchema, payload.workflow_run.head_branch), + { + refType: 'branch' + } + ) + default: + throw new Error(`${eventName} event is not supported.`) + } +}) satisfies ({ + eventName, + payload +}: { + eventName: string + payload: WebhookPayload +}) => string | null diff --git a/src/schema.ts b/src/schema.ts new file mode 100644 index 0000000..c344edd --- /dev/null +++ b/src/schema.ts @@ -0,0 +1,5 @@ +import { nullable, optional, string } from 'valibot' + +export const StringSchema = string() +export const OptionalStringSchema = optional(string()) +export const NullableStringSchema = nullable(string()) diff --git a/tsconfig.json b/tsconfig.json index 2f26aac..7b010e6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,8 @@ "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, - "newLine": "lf" + "newLine": "lf", + "noUncheckedIndexedAccess": true }, "exclude": ["./dist", "./node_modules", "./__tests__", "./coverage"] }