check github_ref tag and sha are checked out on parse

This commit is contained in:
Conor Sloan
2024-04-15 13:45:54 +01:00
parent 507635d01b
commit 17c0582657
10 changed files with 5290 additions and 9 deletions
+2 -2
View File
@@ -8,8 +8,6 @@ export interface PublishActionOptions {
nameWithOwner: string
// The GitHub token to use for API requests
token: string
// The commit SHA to reset back to after the action completes
sha: string
// The base URL for the GitHub API
apiBaseUrl: string
// The base URL for the GitHub Container Registry
@@ -30,6 +28,8 @@ export interface PublishActionOptions {
event: string
// The ref that triggered the action, associated with the event
ref: string
// The commit SHA associated with the ref that triggered the action
sha: string
}
export async function resolvePublishActionOptions(): Promise<PublishActionOptions> {
+26
View File
@@ -4,6 +4,7 @@ import * as path from 'path'
import * as tar from 'tar'
import * as archiver from 'archiver'
import * as crypto from 'crypto'
import * as simpleGit from 'simple-git'
export interface FileMetadata {
path: string
@@ -114,6 +115,31 @@ export function stageActionFiles(actionDir: string, targetDir: string): void {
}
}
// Ensure the correct SHA is checked out for the tag by inspecting the git metadata in the workspace
// and comparing it to the information actions provided us.
// Provided ref should be in format refs/tags/<tagname>.
export async function ensureCorrectShaCheckedOut(
tagRef: string,
expectedSha: string,
gitDir: string
): Promise<void> {
const git: simpleGit.SimpleGit = simpleGit.simpleGit(gitDir)
const tagCommitSha = await git.raw(['rev-parse', '--verify', tagRef])
if (tagCommitSha.trim() !== expectedSha) {
throw new Error(
`The commit associated with the tag ${tagRef} does not match the SHA of the commit provided by the actions context.`
)
}
const currentlyCheckedOutSha = await git.revparse(['HEAD'])
if (currentlyCheckedOutSha.trim() !== expectedSha) {
throw new Error(
`The expected commit associated with the tag ${tagRef} is not checked out.`
)
}
}
// Converts a file path to a filemetadata object by querying the fs for relevant metadata.
async function fileMetadata(filePath: string): Promise<FileMetadata> {
const stats = fs.statSync(filePath)
+10 -2
View File
@@ -18,7 +18,7 @@ export async function run(): Promise<void> {
core.info(`Publishing action package version with options:`)
core.info(cfg.serializeOptions(options))
const semverTag: semver.SemVer = parseSemverTagFromRef(options.ref)
const semverTag: semver.SemVer = await parseSemverTagFromRef(options)
const stagedActionFilesDir = fsHelper.createTempDir(
options.runnerTempDir,
@@ -77,7 +77,11 @@ export async function run(): Promise<void> {
// This action can be triggered by any workflow that specifies a tag as its GITHUB_REF.
// This includes releases, creating or pushing tags, or workflow_dispatch.
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#about-events-that-trigger-workflows.
function parseSemverTagFromRef(ref: string): semver.SemVer {
async function parseSemverTagFromRef(
opts: cfg.PublishActionOptions
): Promise<semver.SemVer> {
const ref = opts.ref
if (!ref.startsWith('refs/tags/')) {
throw new Error(`The ref ${ref} is not a valid tag reference.`)
}
@@ -89,6 +93,10 @@ function parseSemverTagFromRef(ref: string): semver.SemVer {
`${rawTag} is not a valid semantic version tag, and so cannot be uploaded to the action package.`
)
}
// Ensure the correct SHA is checked out for the tag we're parsing, otherwise the bundled content will be incorrect.
await fsHelper.ensureCorrectShaCheckedOut(ref, opts.sha, opts.workspaceDir)
return semverTag
}