Tying up loose ends (#54)
* various qol updates to publish action * review comments and run bundle
This commit is contained in:
+64
-52
@@ -3,8 +3,8 @@ import * as github from '@actions/github'
|
||||
import * as fsHelper from './fs-helper'
|
||||
import * as ociContainer from './oci-container'
|
||||
import * as ghcr from './ghcr-client'
|
||||
import * as api from './api-client'
|
||||
import semver from 'semver'
|
||||
import crypto from 'crypto'
|
||||
|
||||
/**
|
||||
* The main function for the action.
|
||||
@@ -14,82 +14,62 @@ export async function run(pathInput: string): Promise<void> {
|
||||
const tmpDirs: string[] = []
|
||||
|
||||
try {
|
||||
// Parse and validate Actions execution context, including the repository name, release name and event type
|
||||
const repository: string = process.env.GITHUB_REPOSITORY || ''
|
||||
|
||||
if (repository === '') {
|
||||
core.setFailed(`Could not find Repository.`)
|
||||
return
|
||||
}
|
||||
|
||||
if (github.context.eventName !== 'release') {
|
||||
core.setFailed('Please ensure you have the workflow trigger as release.')
|
||||
const token: string = process.env.TOKEN || ''
|
||||
const sourceCommit: string = process.env.GITHUB_SHA || ''
|
||||
if (token === '') {
|
||||
core.setFailed(`Could not find GITHUB_TOKEN.`)
|
||||
return
|
||||
}
|
||||
if (sourceCommit === '') {
|
||||
core.setFailed(`Could not find source commit.`)
|
||||
return
|
||||
}
|
||||
|
||||
const releaseId: string = github.context.payload.release.id
|
||||
const releaseTag: string = github.context.payload.release.tag_name
|
||||
// Strip any leading 'v' from the tag in case the release format is e.g. 'v1.0.0' as recommended by GitHub docs
|
||||
// https://docs.github.com/en/actions/creating-actions/releasing-and-maintaining-actions
|
||||
const targetVersion = semver.parse(releaseTag.replace(/^v/, ''))
|
||||
if (!targetVersion) {
|
||||
core.setFailed(
|
||||
`${releaseTag} is not a valid semantic version, and so cannot be uploaded as an Immutable Action.`
|
||||
)
|
||||
return
|
||||
}
|
||||
const semanticVersion = parseSourceSemanticVersion()
|
||||
|
||||
const token: string = process.env.TOKEN!
|
||||
|
||||
const { consolidatedPath, needToCleanUpDir } =
|
||||
fsHelper.getConsolidatedDirectory(pathInput)
|
||||
if (needToCleanUpDir) {
|
||||
tmpDirs.push(consolidatedPath)
|
||||
}
|
||||
|
||||
if (!fsHelper.isActionRepo(consolidatedPath)) {
|
||||
core.setFailed(
|
||||
'action.y(a)ml not found. Action packages can be created only for action repositories.'
|
||||
)
|
||||
return
|
||||
}
|
||||
// Create a temporary directory to stage files for packaging in archives
|
||||
const stagedActionFilesDir = fsHelper.createTempDir()
|
||||
tmpDirs.push(stagedActionFilesDir)
|
||||
fsHelper.stageActionFiles('.', stagedActionFilesDir)
|
||||
|
||||
// Create a temporary directory to store the archives
|
||||
const archiveDir = fsHelper.createTempDir()
|
||||
tmpDirs.push(archiveDir)
|
||||
const archives = await fsHelper.createArchives(
|
||||
stagedActionFilesDir,
|
||||
archiveDir
|
||||
)
|
||||
|
||||
const archives = await fsHelper.createArchives(consolidatedPath, archiveDir)
|
||||
const { repoId, ownerId } = await api.getRepositoryMetadata(
|
||||
repository,
|
||||
token
|
||||
)
|
||||
|
||||
const manifest = ociContainer.createActionPackageManifest(
|
||||
archives.tarFile,
|
||||
archives.zipFile,
|
||||
repository,
|
||||
targetVersion.raw,
|
||||
repoId,
|
||||
ownerId,
|
||||
sourceCommit,
|
||||
semanticVersion.raw,
|
||||
new Date()
|
||||
)
|
||||
|
||||
// Generate SHA-256 hash of the manifest
|
||||
const manifestSHA = crypto.createHash('sha256')
|
||||
const manifestHash = manifestSHA
|
||||
.update(JSON.stringify(manifest))
|
||||
.digest('hex')
|
||||
const containerRegistryURL = await api.getContainerRegistryURL()
|
||||
console.log(`Container registry URL: ${containerRegistryURL}`)
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.GITHUB_API_URL}/packages/container-registry-url`
|
||||
)
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch status page: ${response.statusText}`)
|
||||
}
|
||||
const data = await response.json()
|
||||
const registryURL: URL = new URL(data.url)
|
||||
console.log(`Container registry URL: ${registryURL}`)
|
||||
|
||||
const packageURL = await ghcr.publishOCIArtifact(
|
||||
const { packageURL, manifestDigest } = await ghcr.publishOCIArtifact(
|
||||
token,
|
||||
registryURL,
|
||||
containerRegistryURL,
|
||||
repository,
|
||||
releaseId.toString(),
|
||||
targetVersion.raw,
|
||||
semanticVersion.raw,
|
||||
archives.zipFile,
|
||||
archives.tarFile,
|
||||
manifest,
|
||||
@@ -98,7 +78,7 @@ export async function run(pathInput: string): Promise<void> {
|
||||
|
||||
core.setOutput('package-url', packageURL.toString())
|
||||
core.setOutput('package-manifest', JSON.stringify(manifest))
|
||||
core.setOutput('package-manifest-sha', `sha256:${manifestHash}`)
|
||||
core.setOutput('package-manifest-sha', `sha256:${manifestDigest}`)
|
||||
} catch (error) {
|
||||
// Fail the workflow run if an error occurs
|
||||
if (error instanceof Error) core.setFailed(error.message)
|
||||
@@ -111,3 +91,35 @@ export async function run(pathInput: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This action can be triggered by release events or tag push events.
|
||||
// In each case, the source event should produce a Semantic Version compliant tag representing the code to be packaged.
|
||||
function parseSourceSemanticVersion(): semver.SemVer {
|
||||
const event = github.context.eventName
|
||||
var semverTag = ''
|
||||
|
||||
// Grab the raw tag
|
||||
if (event === 'release') semverTag = github.context.payload.release.tag_name
|
||||
else if (event === 'push' && github.context.ref.startsWith('refs/tags/')) {
|
||||
semverTag = github.context.ref.replace(/^refs\/tags\//, '')
|
||||
} else {
|
||||
throw new Error(
|
||||
`This action can only be triggered by release events or tag push events.`
|
||||
)
|
||||
}
|
||||
|
||||
if (semverTag === '') {
|
||||
throw new Error(
|
||||
`Could not find a Semantic Version tag in the event payload.`
|
||||
)
|
||||
}
|
||||
|
||||
const semanticVersion = semver.parse(semverTag.replace(/^v/, ''))
|
||||
if (!semanticVersion) {
|
||||
throw new Error(
|
||||
`${semverTag} is not a valid semantic version, and so cannot be uploaded as an Immutable Action.`
|
||||
)
|
||||
}
|
||||
|
||||
return semanticVersion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user