Skip to content

Empty commit

Empty commit #710

Workflow file for this run

name: deploy
on:
issue_comment:
types: [ created ]
env:
ARTIFACT_NAME: 'lambda'
AWS_ACCOUNT_ID: ${{ vars.AWS_ACCOUNT_ID }}
AWS_REGION: ${{ vars.AWS_REGION }}
LAMBDA_FUNCTION: 'alexa-london-travel'
TERM: xterm
permissions:
contents: read
jobs:
setup:
runs-on: ubuntu-latest
if: |
github.event.issue.pull_request != '' &&
github.event.repository.fork == false &&
github.triggering_actor == github.event.repository.owner.login &&
startsWith(github.event.comment.body, '/deploy')
outputs:
comment-id: ${{ steps.post-comment.outputs.result }}
environment-name: ${{ steps.set-outputs.outputs.environment-name }}
environment-url: ${{ steps.set-outputs.outputs.environment-url }}
function-architectures: ${{ steps.set-outputs.outputs.function-architectures }}
function-description: ${{ steps.set-outputs.outputs.function-description }}
function-handler: ${{ steps.set-outputs.outputs.function-handler }}
function-memory: ${{ steps.set-outputs.outputs.function-memory }}
function-name: ${{ steps.set-outputs.outputs.function-name }}
function-runtime: ${{ steps.set-outputs.outputs.function-runtime }}
function-timeout: ${{ steps.set-outputs.outputs.function-timeout }}
ref: ${{ steps.set-outputs.outputs.ref }}
run-id: ${{ steps.set-outputs.outputs.run-id }}
workflow-url: ${{ steps.set-outputs.outputs.workflow-url }}
permissions:
actions: read
contents: read
pull-requests: write
steps:
- name: Get environment name
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: get-environment-name
with:
result-encoding: string
script: |
const owner = context.payload.repository.owner.login;
const repo = context.payload.repository.name;
const username = context.payload.comment.user.login;
try {
await github.rest.repos.checkCollaborator({
owner,
repo,
username,
});
} catch (err) {
throw new Error(`Error: @${username} is not a repository collaborator.`);
}
const comment = context.payload.comment.body;
const regex = /^\/deploy(\s+([a-zA-Z\d\-\_]+))?\s*$/;
const arguments = regex.exec(comment);
if (!arguments || arguments.length < 1) {
throw new Error(`Invalid command: ${comment}`);
}
return arguments[2] || 'dev';
- name: 'Find run for #${{ github.event.issue.number }}'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: get-run
env:
PULL_NUMBER: ${{ github.event.issue.number }}
WORKFLOW_NAME: 'build'
with:
script: |
const pull_number = process.env.PULL_NUMBER;
const workflowName = process.env.WORKFLOW_NAME;
const owner = context.repo.owner;
const repo = context.repo.repo;
core.debug(`Getting pull request ${owner}/${repo}#${pull_number}`);
const { data: pull } = await github.rest.pulls.get({
owner,
repo,
pull_number,
});
if (!pull) {
throw new Error(`Pull request ${owner}/${repo}#${pull_number} not found.`);
}
const head_sha = pull.head.sha;
core.debug(`Getting workflow runs for ${owner}/${repo}#${pull_number}@${head_sha}`);
const { data: workflows } = await github.rest.actions.listWorkflowRunsForRepo({
owner,
repo,
event: 'pull_request',
head_sha,
status: 'success',
});
const run = workflows.workflow_runs.find((run) => run.name === workflowName);
if (!run) {
throw new Error(`No successful workflow run found for ${owner}/${repo}@${head_sha.slice(0, 7)} with name ${workflowName}.`);
}
core.setOutput('ref', head_sha);
core.setOutput('run-id', run.id);
core.setOutput('run-number', run.run_number);
- name: 'Download artifact from #${{ github.event.issue.number }}'
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
name: ${{ env.ARTIFACT_NAME }}
run-id: ${{ steps.get-run.outputs.run-id }}
- name: Set outputs
id: set-outputs
env:
LAMBDA_ARTIFACT_REF: ${{ steps.get-run.outputs.ref }}
LAMBDA_ARTIFACT_RUN_ID: ${{ steps.get-run.outputs.run-id }}
LAMBDA_ARTIFACT_RUN_NUMBER: ${{ steps.get-run.outputs.run-number }}
LAMBDA_ENVIRONMENT: ${{ steps.get-environment-name.outputs.result }}
shell: bash
run: |
environment_name="${LAMBDA_ENVIRONMENT}"
lambda_config="$(unzip -p "${LAMBDA_FUNCTION}.zip" aws-lambda-tools-defaults.json)"
if [ "${environment_name}" == "production" ]
then
function_name="${LAMBDA_FUNCTION}"
else
function_name="${LAMBDA_FUNCTION}-${environment_name}"
fi
environment_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/deployments/${environment_name}"
function_architectures="$(echo "${lambda_config}" | jq -r '."function-architecture"')"
function_description="Deploy build ${LAMBDA_ARTIFACT_RUN_NUMBER} to AWS Lambda via GitHub Actions"
function_handler="$(echo "${lambda_config}" | jq -r '."function-handler"')"
function_memory="$(echo "${lambda_config}" | jq -r '."function-memory-size"')"
function_runtime="$(echo "${lambda_config}" | jq -r '."function-runtime"')"
function_timeout="$(echo "${lambda_config}" | jq -r '."function-timeout"')"
workflow_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
{
echo "environment-name=${environment_name}"
echo "environment-url=${environment_url}"
echo "function-architectures=${function_architectures}"
echo "function-description=${function_description}"
echo "function-handler=${function_handler}"
echo "function-memory=${function_memory}"
echo "function-name=${function_name}"
echo "function-runtime=${function_runtime}"
echo "function-timeout=${function_timeout}"
echo "ref=${LAMBDA_ARTIFACT_REF}"
echo "run-id=${LAMBDA_ARTIFACT_RUN_ID}"
echo "workflow-url=${workflow_url}"
} >> "$GITHUB_OUTPUT"
- name: Post comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: post-comment
env:
ENVIRONMENT_NAME: ${{ steps.set-outputs.outputs.environment-name }}
ENVIRONMENT_URL: ${{ steps.set-outputs.outputs.environment-url }}
WORKFLOW_URL: ${{ steps.set-outputs.outputs.workflow-url }}
with:
result-encoding: string
script: |
const owner = context.payload.repository.owner.login;
const repo = context.payload.repository.name;
const issue_number = context.issue.number;
const environment = process.env.ENVIRONMENT_NAME;
const environment_url = process.env.ENVIRONMENT_URL;
const workflow_url = process.env.WORKFLOW_URL;
const { data: comment } = await github.rest.issues.createComment({
owner,
repo,
issue_number,
body: `Starting [deployment](${workflow_url}) to [${environment}](${environment_url}) :rocket:`,
});
return comment.id;
deploy:
name: ${{ needs.setup.outputs.environment-name }}
needs: [ setup ]
concurrency: '${{ needs.setup.outputs.environment-name }}_environment'
runs-on: ubuntu-latest
env:
FUNCTION_NAME: ${{ needs.setup.outputs.function-name }}
LAMBDA_ARCHITECTURES: ${{ needs.setup.outputs.function-architectures }}
LAMBDA_DESCRIPTION: ${{ needs.setup.outputs.function-description }}
LAMBDA_HANDLER: ${{ needs.setup.outputs.function-handler }}
LAMBDA_MEMORY: ${{ needs.setup.outputs.function-memory }}
LAMBDA_ROLE: ${{ vars.AWS_LAMBDA_ROLE }}
LAMBDA_RUNTIME: ${{ needs.setup.outputs.function-runtime }}
LAMBDA_TIMEOUT: ${{ needs.setup.outputs.function-timeout }}
environment:
name: ${{ needs.setup.outputs.environment-name }}
permissions:
id-token: write
pull-requests: write
steps:
- name: Download artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
name: ${{ env.ARTIFACT_NAME }}
run-id: ${{ needs.setup.outputs.run-id }}
- name: Get Lambda environment variables
env:
SKILL_API_URL: ${{ vars.SKILL_API_URL }}
SKILL_ID: ${{ secrets.SKILL_ID }}
TFL_APPLICATION_ID: ${{ secrets.TFL_APPLICATION_ID }}
TFL_APPLICATION_KEY: ${{ secrets.TFL_APPLICATION_KEY }}
VERIFY_SKILL_ID: "true"
shell: bash
run: |
lambda_vars="{\
\"Variables\": {\
\"SSL_CERT_FILE\": \"/tmp/noop\",\
\"Skill__SkillApiUrl\": \"${SKILL_API_URL}\",\
\"Skill__SkillId\": \"${SKILL_ID}\",\
\"Skill__TflApplicationId\": \"${TFL_APPLICATION_ID}\",\
\"Skill__TflApplicationKey\": \"${TFL_APPLICATION_KEY}\",\
\"Skill__VerifySkillId\": \"${VERIFY_SKILL_ID}\"\
}\
}"
echo "LAMBDA_ENVIRONMENT_VARIABLES=${lambda_vars}" >> "$GITHUB_ENV"
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/github-actions-deploy
role-session-name: ${{ github.event.repository.name }}-${{ github.run_id }}-deploy-${{ needs.setup.outputs.environment-name }}
aws-region: ${{ env.AWS_REGION }}
- name: Update function code
shell: bash
run: |
aws lambda update-function-code \
--function-name "${FUNCTION_NAME}" \
--architectures "${LAMBDA_ARCHITECTURES}" \
--zip-file "fileb://./${LAMBDA_FUNCTION}.zip"
- name: Wait for function code update
shell: bash
run: |
aws lambda wait function-updated-v2 \
--function-name "${FUNCTION_NAME}"
- name: Update function configuration
shell: bash
env:
LAMBDA_LAYERS: ${{ vars.AWS_LAMBDA_LAYERS }}
LAMBDA_LOGGING_CONFIG: ${{ vars.AWS_LAMBDA_LOGGING_CONFIG }}
LAMBDA_TRACING_MODE: ${{ vars.AWS_TRACING_MODE }}
run: |
aws lambda update-function-configuration \
--function-name "${FUNCTION_NAME}" \
--description "${LAMBDA_DESCRIPTION}" \
--environment "${LAMBDA_ENVIRONMENT_VARIABLES}" \
--handler "${LAMBDA_HANDLER}" \
--layers "${LAMBDA_LAYERS}" \
--logging-config "${LAMBDA_LOGGING_CONFIG}" \
--memory-size "${LAMBDA_MEMORY}" \
--role "${LAMBDA_ROLE}" \
--runtime "${LAMBDA_RUNTIME}" \
--timeout "${LAMBDA_TIMEOUT}" \
--tracing-config "Mode=${LAMBDA_TRACING_MODE}"
- name: Wait for function configuration update
shell: bash
run: |
aws lambda wait function-updated-v2 \
--function-name "${FUNCTION_NAME}"
- name: Post comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: ${{ !cancelled() }}
env:
COMMENT_ID: ${{ needs.setup.outputs.comment-id }}
ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }}
ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }}
OUTCOME: ${{ job.status }}
WORKFLOW_URL: ${{ needs.setup.outputs.workflow-url }}
with:
script: |
const owner = context.payload.repository.owner.login;
const repo = context.payload.repository.name;
const comment_id = process.env.COMMENT_ID;
const environment = process.env.ENVIRONMENT_NAME;
const environment_url = process.env.ENVIRONMENT_URL;
const workflow_url = process.env.WORKFLOW_URL;
const succeeded = process.env.OUTCOME === 'success';
const outcome = succeeded ? 'successful' : 'failed';
const emoji = succeeded ? ':white_check_mark:' : ':x:';
await github.rest.issues.updateComment({
owner,
repo,
comment_id,
body: `[Deployment](${workflow_url}) to [${environment}](${environment_url}) ${outcome} ${emoji}`,
});
tests:
name: tests-${{ needs.setup.outputs.environment-name }}
needs: [ setup, deploy ]
runs-on: ubuntu-latest
concurrency: '${{ needs.setup.outputs.environment-name }}_environment'
env:
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
DOTNET_NOLOGO: true
DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1
NUGET_XMLDOC_MODE: skip
permissions:
id-token: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ needs.setup.outputs.ref }}
- name: Setup .NET SDK
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/github-actions-test
role-session-name: ${{ github.event.repository.name }}-${{ github.run_id }}-tests-${{ needs.setup.outputs.environment-name }}
aws-region: ${{ env.AWS_REGION }}
- name: Run end-to-end tests
shell: pwsh
run: dotnet test ./test/LondonTravel.Skill.EndToEndTests --configuration Release --logger "GitHubActions;report-warnings=false"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LAMBDA_FUNCTION_NAME: ${{ needs.setup.outputs.function-name }}
LWA_CLIENT_ID: ${{ secrets.LWA_CLIENT_ID }}
LWA_CLIENT_SECRET: ${{ secrets.LWA_CLIENT_SECRET }}
LWA_REFRESH_TOKEN: ${{ secrets.LWA_REFRESH_TOKEN }}
PULL_NUMBER: ${{ github.event.issue.number }}
SKILL_ID: ${{ secrets.SKILL_ID }}
SKILL_STAGE: development
- name: Post comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: ${{ !cancelled() }}
env:
COMMENT_ID: ${{ needs.setup.outputs.comment-id }}
ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }}
ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }}
OUTCOME: ${{ job.status }}
WORKFLOW_URL: ${{ needs.setup.outputs.workflow-url }}
with:
script: |
const owner = context.payload.repository.owner.login;
const repo = context.payload.repository.name;
const comment_id = process.env.COMMENT_ID;
const environment = process.env.ENVIRONMENT_NAME;
const environment_url = process.env.ENVIRONMENT_URL;
const workflow_url = process.env.WORKFLOW_URL;
const succeeded = process.env.OUTCOME === 'success';
const outcome = succeeded ? 'passed' : 'failed';
const emoji = succeeded ? ':white_check_mark:' : ':x:';
await github.rest.issues.updateComment({
owner,
repo,
comment_id,
body: `:test_tube: [Tests](${workflow_url}) for deployment to [${environment}](${environment_url}) ${outcome} ${emoji}`,
});