generated from actions/typescript-action
-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: initial implemenation of signing action
- Loading branch information
1 parent
4b9371b
commit 8508fe2
Showing
9 changed files
with
928 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
engine-strict=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,60 @@ | ||
name: 'Your name here' | ||
description: 'Provide a description here' | ||
author: 'Your name or organization here' | ||
name: AWS Lambda Code Signing GitHub Action | ||
author: Clowd Haus, LLC | ||
description: GitHub action which uses AWS Code Signer to sign ✍🏼 AWS Lambda artifacts 📦 from your pipeline | ||
branding: | ||
icon: edit | ||
color: orange | ||
|
||
inputs: | ||
milliseconds: # change this | ||
aws-region: | ||
description: AWS Region, e.g. us-east-2 | ||
required: true | ||
description: 'input description here' | ||
default: 'default value if applicable' | ||
client-request-token: | ||
description: >- | ||
String that identifies the signing request. All calls after | ||
the first that use this token return the same response as the first call | ||
required: false | ||
source-s3-bucket: | ||
description: Source S3 bucket name | ||
required: true | ||
source-s3-key: | ||
description: Source S3 object key | ||
required: true | ||
source-s3-version: | ||
description: Source S3 object version | ||
required: true | ||
destination-s3-bucket: | ||
description: Destination S3 bucket name | ||
required: true | ||
destination-s3-prefix: | ||
description: Destination S3 object key prefix | ||
required: false | ||
default: 'signed/' | ||
profile-name: | ||
description: >- | ||
Name of the signing profile to use for signing | ||
required: true | ||
profile-owner: | ||
description: >- | ||
The AWS account ID of the signing profile owner | ||
required: false | ||
rename-signed-object: | ||
description: >- | ||
Rename the generated signed object to match the original | ||
`sourceS3Key` with the `destinationS3Prefix` | ||
required: false | ||
default: 'true' | ||
wait-until-successful: | ||
description: >- | ||
Wait until the signed jobs complete successfully | ||
required: false | ||
default: 'true' | ||
max-wait-time: | ||
description: >- | ||
Maximum amount of time, in seconds, to wait for a job to completely successfully | ||
required: false | ||
default: '30' | ||
|
||
runs: | ||
using: 'node12' | ||
main: 'dist/index.js' |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,34 @@ | ||
import * as core from '@actions/core'; | ||
|
||
async function run(): Promise<void> { | ||
import CodeSigner from './sign'; | ||
import * as input from './input'; | ||
|
||
async function run(actionInput: input.Input): Promise<void> { | ||
try { | ||
const ms: string = core.getInput('milliseconds'); | ||
core.debug(`Waiting ${ms} milliseconds ...`); // debug is only output if you set the secret `ACTIONS_STEP_DEBUG` to true | ||
const signer = await new CodeSigner(actionInput.awsRegion); | ||
const createSignedJob = await signer.createSignedJob(actionInput.jobCommandInput); | ||
if (createSignedJob && createSignedJob.jobId) { | ||
core.debug(`createSignedJob: ${createSignedJob.jobId}`); | ||
} | ||
|
||
if (createSignedJob && createSignedJob.jobId && actionInput.waitUntilSuccessful) { | ||
await signer.waitUntilSuccessful(actionInput.maxWaitTime, createSignedJob.jobId); | ||
} | ||
} catch (error) { | ||
core.setFailed(JSON.stringify(error, null, 4)); | ||
} | ||
} | ||
|
||
core.debug(new Date().toTimeString()); | ||
// await wait(parseInt(ms, 10)) | ||
core.debug(new Date().toTimeString()); | ||
async function main(): Promise<void> { | ||
const actionInput = input.get(); | ||
|
||
core.setOutput('time', new Date().toTimeString()); | ||
try { | ||
if (actionInput) { | ||
await run(actionInput); | ||
} | ||
} catch (error) { | ||
if (error instanceof Error) core.setFailed(error.message); | ||
core.setFailed((<Error>error).message); | ||
} | ||
} | ||
|
||
run(); | ||
void main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Parse action input into a some proper thing. | ||
*/ | ||
|
||
import * as core from '@actions/core'; | ||
import {StartSigningJobCommandInput} from '@aws-sdk/client-signer'; | ||
|
||
export interface Input { | ||
awsRegion: string; | ||
clientRequestToken?: string; | ||
jobCommandInput: StartSigningJobCommandInput; | ||
renameSignedObject: boolean; | ||
waitUntilSuccessful: boolean; | ||
maxWaitTime: number; | ||
} | ||
|
||
// Helper function since only strings are used as inputs | ||
function convertToBoolean(input: string): boolean { | ||
return input.toLowerCase() === 'true'; | ||
} | ||
|
||
export function get(): Input | undefined { | ||
try { | ||
const awsRegion = core.getInput('aws-region', {required: true}); | ||
const clientRequestToken = core.getInput('client-request-token', {required: false}); | ||
const sourceS3Bucket = core.getInput('source-s3-bucket', {required: true}); | ||
const sourceS3Key = core.getInput('source-s3-key', {required: true}); | ||
const sourceS3Version = core.getInput('source-s3-version', {required: true}); | ||
const destinationS3Bucket = core.getInput('destination-s3-bucket', {required: true}); | ||
const destinationS3Prefix = core.getInput('destination-s3-prefix', {required: true}); | ||
const profileName = core.getInput('profile-name', {required: false}); | ||
const profileOwner = core.getInput('profile-owner', {required: false}); | ||
|
||
const renameSignedObject = convertToBoolean(core.getInput('rename-signed-object', {required: false})); | ||
const waitUntilSuccessful = convertToBoolean(core.getInput('wait-until-successful', {required: false})); | ||
const maxWaitTime = parseInt(core.getInput('max-wait-time', {required: false})); | ||
|
||
const jobCommandInput: StartSigningJobCommandInput = { | ||
source: { | ||
s3: { | ||
bucketName: sourceS3Bucket, | ||
key: sourceS3Key, | ||
version: sourceS3Version, | ||
}, | ||
}, | ||
destination: { | ||
s3: { | ||
bucketName: destinationS3Bucket, | ||
prefix: destinationS3Prefix, | ||
}, | ||
}, | ||
profileName: profileName, | ||
...(profileOwner ? {profileName: profileName} : {}), | ||
}; | ||
|
||
return { | ||
awsRegion, | ||
clientRequestToken, | ||
jobCommandInput, | ||
renameSignedObject, | ||
waitUntilSuccessful, | ||
maxWaitTime, | ||
}; | ||
} catch (error) { | ||
core.setFailed((<Error>error).message); | ||
return; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { | ||
SignerClient, | ||
StartSigningJobCommand, | ||
StartSigningJobCommandInput, | ||
StartSigningJobResponse, | ||
waitUntilSuccessfulSigningJob, | ||
} from '@aws-sdk/client-signer'; | ||
// import {WaiterState} from '@aws-sdk/util-waiter'; | ||
|
||
import * as core from '@actions/core'; | ||
|
||
export default class CodeSigner { | ||
readonly region: string; | ||
readonly client: SignerClient; | ||
|
||
constructor(region: string) { | ||
this.region = region; | ||
this.client = new SignerClient({region}); | ||
} | ||
|
||
async createSignedJob(input: StartSigningJobCommandInput): Promise<StartSigningJobResponse> { | ||
try { | ||
const command = new StartSigningJobCommand(input); | ||
// core.debug(JSON.stringify(input, null, 4)); | ||
return await this.client.send(command); | ||
} catch (error) { | ||
const {requestId, cfId, extendedRequestId} = error.$metadata; | ||
console.error({requestId, cfId, extendedRequestId}); | ||
core.setFailed(JSON.stringify(error, null, 4)); | ||
throw error; | ||
} | ||
} | ||
|
||
async waitUntilSuccessful(maxWaitTime: number, jobId: string): Promise<void> { | ||
const waiterConfig = {client: this.client, minDelay: 1, maxDelay: 10, maxWaitTime}; | ||
// core.debug(`waiterConfig: ${JSON.stringify(waiterConfig, null, 4)}`); | ||
|
||
const signingJobInput = {jobId}; | ||
core.debug(`signingJobInput: ${JSON.stringify(signingJobInput, null, 4)}`); | ||
|
||
try { | ||
const waitResult = await waitUntilSuccessfulSigningJob(waiterConfig, signingJobInput); | ||
core.debug(`waitResult: ${JSON.stringify(waitResult, null, 4)}`); | ||
} catch (error) { | ||
core.setFailed(JSON.stringify(error, null, 4)); | ||
} | ||
|
||
// switch (waitResult.state) { | ||
// case WaiterState.SUCCESS: { | ||
// core.debug(waitResult.reason); | ||
// return; | ||
// } | ||
// default: { | ||
// core.setFailed(waitResult.reason); | ||
// return; | ||
// } | ||
// } | ||
} | ||
|
||
static async renameSignedObject(): Promise<void> { | ||
return; | ||
} | ||
} |
Oops, something went wrong.