Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion publish/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "publish",
"version": "1.0.18",
"version": "1.0.19",
"description": "An action that decides if a new release should be published",
"scripts": {
"build": "tsup",
Expand Down
6 changes: 6 additions & 0 deletions version-metadata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ Using this you can easily automate publishing to a package registry such as NPM

This action only computes metadata and doesn't push git tags, publishes a package, creates github releases, etc.

This action has explicit support for the following event types:
- `push`
- `pull_request`
- `issue_comment` (on pull requests)
- `workflow_dispatch` (given ref must be associated with exactly one pull request)
- `merge_group`

## Usage

Expand Down
2 changes: 1 addition & 1 deletion version-metadata/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "version-metadata",
"version": "1.0.18",
"version": "1.0.19",
"description": "An action that checks wether your package.json version has been updated with a bit of additional metadata",
"scripts": {
"build": "tsup",
Expand Down
2 changes: 1 addition & 1 deletion version-metadata/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async function run(): Promise<VersionMetadataResponse> {
// all resolved correctly, just not "the bigger picture" (meaning all useful types in one place).
const octokit = getOctokit(token)

let { base: maybeBase, head } = determineBaseAndHead(context)
let { base: maybeBase, head } = await determineBaseAndHead(octokit, context)

let baseCommitIsIncludedInRange = true

Expand Down
78 changes: 72 additions & 6 deletions version-metadata/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { spawnSync } from 'child_process'
import type { Context } from '@actions/github/lib/context'
import type { getOctokit } from '@actions/github'

type Octokit = ReturnType<typeof getOctokit>

export type VersionDiffType = 'major' | 'minor' | 'patch' | 'pre-release'

export type Unpromise<T> = T extends Promise<infer U> ? U : never
export type Commit = Unpromise<ReturnType<ReturnType<typeof getOctokit>['rest']['repos']['getCommit']>>['data']
export type Commit = Unpromise<ReturnType<Octokit['rest']['repos']['getCommit']>>['data']

type File = {
status: 'added' | 'modified' | 'removed' | 'renamed' | 'copied' | 'changed' | 'unchanged'
Expand Down Expand Up @@ -177,6 +179,56 @@ const computeResponseFromChanges = (
}
}

const getPullRequestFromIssueComment = (octokit: Octokit, context: Context) => {
const issue = context.payload.issue

if (!issue) {
throw new Error('issue_comment event payload does not contain issue information.')
}

if (!issue.pull_request || !issue.pull_request.url) {
throw new Error('The issue comment is not made on a pull request.')
}

return octokit.rest.pulls
.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: issue.number
})
.then((res) => res.data)
}

const getPullRequestFromWorkflowDispatch = async (octokit: Octokit, context: Context) => {
const ref = context.payload.ref

if (!ref) {
throw new Error('workflow_dispatch event does not contain a ref.')
}

if (!ref.startsWith('refs/heads/')) {
throw new Error('workflow_dispatch only works refs pointing to branches associated with a pull request.')
}

const branchName = ref.replace('refs/heads/', '')

const prs = await octokit.rest.pulls
.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${context.repo.owner}:${branchName}`
})
.then((res) => res.data)

if (prs.length !== 1) {
throw new Error(
`workflow_dispatch event on branch '${branchName}' is associated with ${prs.length} pull requests, expected exactly one.`
)
}

return prs[0]
}

/**
* Determines the base and head commits from the payload
*
Expand All @@ -196,7 +248,7 @@ const computeResponseFromChanges = (
*
* (*): For pushes which create a new branch, context.payload.before is all zeroes (40 to be exact), in this case base is returned as undefined
*/
const determineBaseAndHead = (context: Context) => {
const determineBaseAndHead = async (octokit: Octokit, context: Context) => {
// Define the base and head commits to be extracted from the payload.
let base: string | undefined
let head: string | undefined
Expand All @@ -206,6 +258,20 @@ const determineBaseAndHead = (context: Context) => {
base = context.payload.pull_request?.base?.sha
head = context.payload.pull_request?.head?.sha
break
case 'issue_comment':
{
const pullRequest = await getPullRequestFromIssueComment(octokit, context)
base = pullRequest.base?.sha
head = pullRequest.head?.sha
}
break
case 'workflow_dispatch':
{
const pullRequest = await getPullRequestFromWorkflowDispatch(octokit, context)
base = pullRequest.base?.sha
head = pullRequest.head?.sha
}
break
case 'push':
base = context.payload.before
head = context.payload.after
Expand All @@ -225,7 +291,7 @@ const determineBaseAndHead = (context: Context) => {
break
default:
throw new Error(
`This action only supports pull requests, pushes and merge_groups. ${context.eventName} events are not supported. ` +
`This action only supports pull_request, push, issue_comment, workflow_dispatch and merge_group as event types. ${context.eventName} events are not supported. ` +
"Please submit an issue on this action's GitHub repo if you believe this in correct."
)
}
Expand All @@ -241,7 +307,7 @@ const determineBaseAndHead = (context: Context) => {
return { base, head }
}

const getCommit = (octokit: ReturnType<typeof getOctokit>, context: Context, ref: string) =>
const getCommit = (octokit: Octokit, context: Context, ref: string) =>
octokit.rest.repos
.getCommit({
owner: context.repo.owner,
Expand All @@ -256,7 +322,7 @@ const getCommit = (octokit: ReturnType<typeof getOctokit>, context: Context, ref
*
* @returns the found commit and whether it is an initial commit or not (type: 'initial' | 'normal')
*/
const backtrackToFirstBranchRef = async (octokit: ReturnType<typeof getOctokit>, context: Context, headSha: string) => {
const backtrackToFirstBranchRef = async (octokit: Octokit, context: Context, headSha: string) => {
const { data: allBranches } = await octokit.rest.repos.listBranches({
owner: context.repo.owner,
repo: context.repo.repo
Expand Down Expand Up @@ -344,7 +410,7 @@ const prependCommitToCommitComparison = (commit: Commit, comparison: CompareComm
}

const compareCommits = async (
octokit: ReturnType<typeof getOctokit>,
octokit: Octokit,
context: Context,
base: string,
head: string,
Expand Down
32 changes: 32 additions & 0 deletions version-metadata/test/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,38 @@ const tests = [
oldVersion: '1.0.0',
newVersion: '1.0.0'
}
},
{
description:
'Triggers on a pull request comment (`issue_comment`), looks up the corresponding PR, and then continues same as with a `pull_request` event',
pr: '17',
branch: 'testcase-dont-delete-pr',
base: '<omitted>',
head: '<omitted>',
repo: 'Quantco/ui-actions',
event: 'issue_comment',
file: 'version-metadata/package.json',
expected: {
changed: false,
oldVersion: '1.0.18',
newVersion: '1.0.18'
}
},
{
description:
'Triggers on `workflow_dispatch` event, uses the provided `ref` to look up associated pull requests, then continues same as with a `pull_request` event',
pr: '17',
branch: 'testcase-dont-delete-pr',
base: '<omitted>',
head: '<omitted>',
repo: 'Quantco/ui-actions',
event: 'workflow_dispatch',
file: 'version-metadata/package.json',
expected: {
changed: false,
oldVersion: '1.0.18',
newVersion: '1.0.18'
}
}
]

Expand Down
7 changes: 7 additions & 0 deletions version-metadata/test/testrunner.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ const runTest = (test) => {
sha: test.head
}
},
issue: {
number: test.pr,
pull_request: {
url: `https://api.github.com/repos/${test.repo}/pulls/${test.pr}`
}
},
ref: `refs/heads/${test.branch}`,
before: test.base,
after: test.head
}
Expand Down