diff --git a/dist/index.js b/dist/index.js index dafbbeb..61dc6b0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -25892,14 +25892,53 @@ __export(Index_res_exports, { }); module.exports = __toCommonJS(Index_res_exports); +// node_modules/rescript/lib/es6/caml_option.js +function valFromOption(x) { + if (!(x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== void 0)) { + return x; + } + var depth = x.BS_PRIVATE_NESTED_SOME_NONE; + if (depth === 0) { + return; + } else { + return { + BS_PRIVATE_NESTED_SOME_NONE: depth - 1 | 0 + }; + } +} + +// node_modules/@rescript/core/src/Core__Option.res.mjs +function getOr(opt, $$default) { + if (opt !== void 0) { + return valFromOption(opt); + } else { + return $$default; + } +} +function isSome(x) { + return x !== void 0; +} + // src/GH.res.mjs var Core = __toESM(require_core(), 1); var Github = __toESM(require_github(), 1); var import_core = __toESM(require_dist_node8(), 1); var import_plugin_paginate_rest = __toESM(require_dist_node10(), 1); function pullRequestPayload() { - if (Github.context.eventName === "pull_request" && Github.context.payload !== void 0 && Github.context.payload.pull_request !== void 0 && Github.context.payload.repository !== void 0) { - return Github.context.payload; + var payload = getOr(Github.context.payload, { + pull_request: void 0, + repository: void 0 + }); + var pr = payload.pull_request; + if (pr === void 0) { + return; + } + var repo = payload.repository; + if (repo !== void 0 && Github.context.eventName === "pull_request") { + return { + pull_request: pr, + repository: repo + }; } } function pullRequestLabels(payload) { @@ -25925,21 +25964,6 @@ async function changedFiles(payload) { // src/Matching.res.mjs var Minimatch = __toESM(require_minimatch(), 1); -// node_modules/rescript/lib/es6/caml_option.js -function valFromOption(x) { - if (!(x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== void 0)) { - return x; - } - var depth = x.BS_PRIVATE_NESTED_SOME_NONE; - if (depth === 0) { - return; - } else { - return { - BS_PRIVATE_NESTED_SOME_NONE: depth - 1 | 0 - }; - } -} - // node_modules/@rescript/core/src/Core__Array.res.mjs function indexOfOpt(arr, item) { var index = arr.indexOf(item); @@ -25948,11 +25972,6 @@ function indexOfOpt(arr, item) { } } -// node_modules/@rescript/core/src/Core__Option.res.mjs -function isSome(x) { - return x !== void 0; -} - // src/Matching.res.mjs function anyFileMatches(filePaths, pattern) { return pattern.split("\n").some(function(pattern2) { @@ -25975,14 +25994,13 @@ function formatFailureMessage(template, prereqPattern, filePattern, skipLabel) { async function main() { var payload = pullRequestPayload(); if (payload !== void 0) { - var payload$1 = valFromOption(payload); var skipLabel = Core2.getInput("skip-label"); - var prLabels = pullRequestLabels(payload$1); + var prLabels = pullRequestLabels(payload); if (hasLabelMatch(prLabels, skipLabel)) { Core2.info("the skip label " + JSON.stringify(skipLabel) + " is set"); return; } - var filePaths = await changedFiles(payload$1); + var filePaths = await changedFiles(payload); var prereqPattern = Core2.getInput("prereq-pattern"); if (anyFileMatches(filePaths, prereqPattern)) { var filePattern = Core2.getInput("file-pattern"); diff --git a/src/GH.res b/src/GH.res index 06512bf..d2e77ba 100644 --- a/src/GH.res +++ b/src/GH.res @@ -1,15 +1,63 @@ /* TODO - Isolate %raw() code into its own function so its more isolated/obvious - Wrap getInput() into a function that returns option - - Type `context`/contextType so that the "pull_request" and "repository" are optional, but not subfields - - Type the pullRequestPayloadType so that "pull_request" and "repository" are required - - pullRequestPayload() return `option` - - Type paginate() better +*/ + +type labelType = {name: string} + +type prType = { + number: int, + labels: array, +} + +type ownerType = {login: string} + +type repoType = { + name: string, + owner: ownerType, +} + +/** + A payload type that avoids having to go through `option` on all accesses. */ +type prPayloadType = { + pull_request: prType, + repository: repoType, +} -@module("@actions/github") external context: 'whatever = "context" +type payloadType = { + pull_request: option, + repository: option, +} +type contextType = { + eventName: string, + payload: option, +} + +type paginateOptionType = { + owner: string, + repo: string, + pull_number: int, + per_page: int, +} + +type fileDataType = {filename: string} + +type paginateResponseType = {data: array} + +type paginateReturnType = array + +type paginateCallbackType = paginateResponseType => paginateReturnType + +@module("@actions/github") external context: contextType = "context" @module("@actions/core") external getInput: string => string = "getInput" -@send external paginate: ('a, 'b, 'c, 'd) => promise> = "paginate" +@send +external paginate: ( + 'octokit, + string, + paginateOptionType, + paginateCallbackType, +) => promise = "paginate" // Imports used only inside %raw calls; doing this in ReScript would cause the // compiler to drop the imports as unnecessary. %%raw(` @@ -18,34 +66,32 @@ import { paginateRest } from "@octokit/plugin-paginate-rest"; `) /** - * Check if 'github.context.payload' is from a PR, returning it as the appropriate type. + * Check if `github.context.payload` is from a PR, returning it as the appropriate type. * - * Returns 'undefined' if the context is anything but a PR. + * Returns `undefined` if the context is anything but a PR. */ -let pullRequestPayload = () => { - if ( - context["eventName"] == "pull_request" && - context["payload"] != Nullable.undefined && - context["payload"]["pull_request"] != Nullable.undefined && - context["payload"]["repository"] != Nullable.undefined - ) { - // TODO: Can return a specific pullRequestPayloadType to avoid deeply nested option access. - context["payload"] - } else { - None +let pullRequestPayload = (): option => { + let payload = context.payload->Option.getOr({pull_request: None, repository: None}) + + switch payload { + | {pull_request: Some(pr), repository: Some(repo)} if context.eventName == "pull_request" => { + let prPayload: prPayloadType = {pull_request: pr, repository: repo} + Some(prPayload) + } + | _ => None } } /** * Get the labels of the PR. */ -let pullRequestLabels = payload => - payload["pull_request"]["labels"]->Array.map(labelData => labelData["name"]) +let pullRequestLabels = (payload: prPayloadType) => + payload.pull_request.labels->Array.map(labelData => labelData.name) /** * Fetch the list of changed files in the PR. */ -let changedFiles = async payload => { +let changedFiles = async (payload: prPayloadType) => { let octokit = switch getInput("token") { | "" => %raw(`new (Octokit.plugin(paginateRest))()`) // While marked as ignored, `_token` is used inside the %raw() call. @@ -55,11 +101,11 @@ let changedFiles = async payload => { await octokit->paginate( "GET /repos/{owner}/{repo}/pulls/{pull_number}/files", { - "owner": payload["repository"]["owner"]["login"], - "repo": payload["repository"]["name"], - "pull_number": payload["pull_request"]["number"], - "per_page": 100, + owner: payload.repository.owner.login, + repo: payload.repository.name, + pull_number: payload.pull_request.number, + per_page: 100, }, - response => response["data"]->Array.map(fileData => fileData["filename"]), + response => response.data->Array.map(fileData => fileData.filename), ) } diff --git a/src/Main.res b/src/Main.res index e12163d..e3a3e02 100644 --- a/src/Main.res +++ b/src/Main.res @@ -17,7 +17,7 @@ let formatFailureMessage = (template, prereqPattern, filePattern, skipLabel) => let main = async (): unit => { switch GH.pullRequestPayload() { - | None => logInfo(`${repr(GH.context["eventName"])} is not a pull request event; skipping`) + | None => logInfo(`${repr(GH.context.eventName)} is not a pull request event; skipping`) | Some(payload) => { let skipLabel = GH.getInput("skip-label") let prLabels = GH.pullRequestLabels(payload)