Skip to content

EN-23320 - Adding Teams action in reusable workflows #4

EN-23320 - Adding Teams action in reusable workflows

EN-23320 - Adding Teams action in reusable workflows #4

# The purpose of this reusable job is to run the final steps of a deployment workflow
# which includes updating the github deployments in TechHub and posting a status to Teams.
# Example Usage in a repo's workflow:
# jobs:
# update-github-deployments-and-send-teams-notification:
# uses: im-practices/.github/.github/workflows/im-reusable-finish-deployment-workflow.yml@v3
# with:
# runs-on: im-linux
# gh-secrets-environment: ${{ inputs.environment-or-target }}
# deployment-environment: ${{ needs.set-vars.outputs.GH_SECRETS_ENVIRONMENT}}
# release-tag: ${{ inputs.tag }}
# title-of-teams-post: 'Deploy ${{ needs.set-vars.outputs.AZ_APP_NAME }} ${{ inputs.tag }} to ${{ inputs.environment-or-target }}'
# post-status-in-deployment-notifications-channel: true
# timezone: america/denver
# custom-facts-for-team-channel: |
# [
# { "name": "Workflow", "value": "${{ github.workflow }}" },
# { "name": "Run", "value": "${{ github.run_id }}" },
# { "name": "Actor", "value": "${{ github.actor }}" },
# { "name": "Version", "value": "${{ inputs.tag }}" }
# ]
# custom-facts-for-deployment-notifications-channel: |
# [
# { "name": "Actor", "value": "${{ github.actor }}" },
# { "name": "Version", "value": "${{ inputs.tag }}" }
# ]
# ms-teams-uri: ${{ vars.MS_TEAMS_URI }} # Use this input (preferred) or the secret
# deploy-notifications-channel: ${{ vars.DEPLOY_NOTIFICATIONS_CHANNEL }} # This is an org-level variable
# entity: ${{ env.TECHHUB_ENTITY }}
# instance: ${{ env.TECHHUB_INSTANCE }}
on:
workflow_call:
inputs:
# Required Inputs
deployment-environment:
description: 'The environment that was deployed to: dev, qa, stage, stage-secondary, uat, demo, prod, prod-secondary.'
required: true
type: string
gh-secrets-environment:
description: 'The GitHub environment secrets should be accessed from: dev, qa, stage, uat, demo, prod.'
required: true
type: string
release-tag:
description: 'The tag of the release being deployed.'
required: true
type: string
title-of-teams-post:
description: 'Title of the Teams post that will be used in the team channel and the Deployment Notifications channel.'
required: true
type: string
deploy-notifications-channel:
description: 'The URI for the notifications channel where a status will be posted.'
required: true
type: string
entity:
description: 'The TechHub entity that is being deployed. This value should match the metadata.name of the entity defined in catalog-info.yml.'
required: true
type: string
instance:
description: |
The value used to create a deployment instance name in the GitHub deployment API.
It represents the specific target deployment location e.g., primary, primary-app-service, testing-slot, failover-slot-2, NA26, NA27-production-slot
Generally some combination of deployment-environment, slot-name and AZ region values.
required: true
type: string
# Optional Inputs
runs-on:
description: 'The runner that this workflow will run on.'
required: false
type: string
default: 'im-linux'
post-status-in-deployment-notifications-channel:
description: 'Flag indicating whether a post should be made to the Deployment Notifications channel.'
required: false
type: boolean
default: true
timezone:
description: 'Timezone for the project. Defaults to america/denver.'
required: false
type: string
default: 'america/denver'
custom-facts-for-team-channel:
description: The custom facts that will be included in the post in the team's channel. By default Workflow, Run, Actor and Version are included.
required: false
type: string
custom-actions-for-team-channel:
description: The custom actions that will be included in the post in the team's channel.
required: false
type: string
custom-facts-for-deployment-notifications-channel:
description: 'The custom facts that will be included in the Deployment Notifications channel.'
required: false
type: string
custome-actions-for-deployment-notifications-channel:

Check failure on line 97 in .github/workflows/im-reusable-finish-deployment-workflow.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/im-reusable-finish-deployment-workflow.yml

Invalid workflow file

You have an error in your yaml syntax on line 97
description: 'The custom actions that will be included in the post in the Deployment Notifications channel. By default the actions are 'View in TechHub' and 'View in GitHub'.'
required: false
type: string
ms-teams-uri:
description: The URI for the teams channel where a status will be posted. Either this value or the secret MS_TEAMS_URI must be provided. This input is the preferred way to provide the URI but the secret should be used instead if the value is defined as a secret.
required: false
type: string
secrets:
MS_TEAMS_URI:
description: 'The URI for the teams channel where a status will be posted. Either this value or the input ms-teams-uri must be provided. The input is the preferred way to provide the URI but the secret should be used if the value is defined as a secret.'
required: false
jobs:
finish-deployment-workflow:
runs-on: ${{ inputs.runs-on }}
environment: ${{ inputs.gh-secrets-environment }}
steps:
- name: Check for missing inputs
uses: actions/github-script@v7
with:
script: |
// Some teams have these as a secret and some as a var, allow both ways but check at least one is present
const teamsUri = '${{ inputs.ms-teams-uri || secrets.MS_TEAMS_URI }}';
if (!teamsUri || teamsUri.trim().length === 0){
core.setFailed('The MS_TEAMS_URI secret or the ms-teams-uri input (preferred) must be provided.');
}
- name: Print inputs
uses: actions/github-script@v7
with:
script: |
function printInput(inputName, inputValue, isMultilineInput){
if (!inputValue || inputValue.trim().length === 0){
core.info(`${inputName}: Not Provided`);
} else if (isMultilineInput){
console.log(`\n${inputName}:\n${inputValue}`);
}
else {
core.info(`${inputName}: ${inputValue}`);
}
}
core.startGroup('Reusable workflow inputs');
printInput('deployment-environment', '${{ inputs.deployment-environment }}');
printInput('gh-secrets-environment', '${{ inputs.gh-secrets-environment }}');
printInput('release-tag', '${{ inputs.release-tag }}');
printInput('title-of-teams-post', '${{ inputs.title-of-teams-post }}');
printInput('runs-on', '${{ inputs.runs-on }}');
printInput('post-status-in-deployment-notifications-channel', '${{ inputs.post-status-in-deployment-notifications-channel }}');
printInput('timezone', '${{ inputs.timezone }}');
printInput('instance', '${{ inputs.instance }}');
printInput('ms-teams-uri', '${{ inputs.ms-teams-uri }}');
printInput('deploy-notifications-channel', '${{ inputs.deploy-notifications-channel }}');
printInput('custom-facts-for-team-channel', process.env.CUSTOM_FACTS_TEAMS, true);
printInput('custom-actions-for-team-channel', process.env.CUSTOM_ACTIONS_TEAMS, true);
printInput('custom-facts-for-deployment-notifications-channel', process.env.CUSTOM_FACTS_DEPLOY, true);
printInput('custom-actions-for-deployment-notifications-channel', process.env.CUSTOM_ACTIONS_DEPLOY, true);
core.endGroup();
core.startGroup('Reusable workflow secrets');
printInput('MS_TEAMS_URI', '${{ secrets.MS_TEAMS_URI }}');
core.endGroup();
env:
CUSTOM_FACTS_TEAMS: ${{ inputs.custom-facts-for-team-channel }}
CUSTOM_ACTIONS_TEAMS: ${{ inputs.custom-actions-for-team-channel }}
CUSTOM_FACTS_DEPLOY: ${{ inputs.custom-facts-for-deployment-notifications-channel }}
CUSTOM_ACTIONS_DEPLOY: ${{ inputs.custom-actions-for-deployment-notifications-channel }}
- uses: im-open/[email protected]
id: conclusion
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# Only run this step if TechHub metadata.name value
# and a metadata.instance value are provided
- name: Create GitHub Deployment for TechHub
uses: im-open/[email protected]
with:
workflow-actor: ${{ github.actor }} # This will add the user who kicked off the workflow to the deployment payload
token: ${{ secrets.GITHUB_TOKEN }} # Special per-job token generated by GH for interacting with the repo
environment: ${{ inputs.deployment-environment }}
release-ref: ${{ inputs.release-tag }}
deployment-status: ${{ steps.conclusion.outputs.workflow_conclusion }}
deployment-description: 'Deployment to the ${{ inputs.deployment-environment }} environment of ${{ inputs.release-tag }}'
entity: ${{ inputs.entity }}
instance: ${{ inputs.instance }}
- name: Configure facts for team's notification channel
if: always()
id: team-channel-facts
uses: actions/github-script@v7
with:
script: |
const rawFacts = process.env.FACTS;
console.log(`"${rawFacts}"`);
let facts = rawFacts && rawFacts.trim().length > 0 ? JSON.parse(rawFacts) : null;
if (!facts || facts.length === 0){
console.log(`Custom facts were not provided for the Team's Notification channel, use the default facts:`);
facts = [
{ name: 'Workflow', value: '${{ github.workflow }}'},
{ name: 'Run', value: '${{ github.run_id }}'},
{ name: 'Actor', value: '${{ github.actor }}'},
{ name: 'Version', value: '${{ inputs.release-tag }}'}
]
}
else {
console.log(`Custom facts were supplied as an argument, using those in the Team's Notification channel:`);
}
console.log(facts);
core.setOutput('facts', facts);
env:
FACTS: ${{ inputs.custom-facts-for-team-channel }}
- name: Send status to team's notification channel
if: always()
uses: im-open/[email protected]
with:
title: ${{ inputs.title-of-teams-post }}
workflow-status: ${{ steps.conclusion.outputs.workflow_conclusion }}
workflow-type: Deploy
teams-uri: ${{ inputs.ms-teams-uri || secrets.MS_TEAMS_URI }}
timezone: ${{ inputs.timezone }}
custom-facts: ${{ steps.team-channel-facts.outputs.facts }}
custom-actions: ${{ inputs.custom-actions-for-team-channel }}
- name: Determine if a post should be made in Deployment Notifications channel
if: always()
id: post-to-deployment-channel
uses: actions/github-script@v7
with:
script: |
const postInProd = ${{ inputs.post-status-in-deployment-notifications-channel }};
const deployEnv = '${{ inputs.deployment-environment }}';
const workflowConclusion = '${{ steps.conclusion.outputs.workflow_conclusion }}';
const isProdEnv = deployEnv === 'prod' || deployEnv === 'prod-secondary';
const post = postInProd && isProdEnv && workflowConclusion === 'success';
core.setOutput('post', post);
const message = `Values used to determine if a Deployment Notifications post will be made:
\tpost-status-in-deployment-notifications-channel input: ${postInProd}\t(must be true to post)
\tWorkflow Conclusion: ${workflowConclusion} \t\t(must be 'success' to post)
\tEnvironment: ${deployEnv} \t(must be 'prod' or 'prod-secondary' to post)`;
console.log(message);
if (!post) {
console.log('The conditions were not satisfied and a post will not be made in the Deployment Notifications channel.');
} else {
console.log('The conditions were statisfied so a post will be made in the Deployment Notifications channel.');
}
- name: Configure facts for Deployment Notifications channel
if: always() && steps.post-to-deployment-channel.outputs.post == 'true'
id: deployment-channel-facts
uses: actions/github-script@v7
with:
script: |
const rawFacts = process.env.FACTS;
let facts = rawFacts && rawFacts.trim().length > 0 ? JSON.parse(rawFacts) : null;
if (!facts || facts.length === 0){
console.log('Custom facts were not provided for the Deployment Notifications channel, use the default facts:');
facts = [
{ name: 'Actor', value: '${{ github.actor }}'},
{ name: 'Version', value: '${{ inputs.release-tag }}'}
]
}
else {
console.log('Custom facts were supplied as an argument, using those in the Deployment Notifications channel:');
}
console.log(facts);
core.setOutput('facts', facts);
env:
FACTS: ${{ inputs.custom-facts-for-deployment-notifications-channel }}
- name: Send Status to Deployment Notifications Channel for Prod Deploys
if: always() && steps.post-to-deployment-channel.outputs.post == 'true'
uses: im-open/[email protected]
with:
title: ${{ inputs.title-of-teams-post }}
workflow-status: ${{ steps.conclusion.outputs.workflow_conclusion }}
workflow-type: Deploy
teams-uri: ${{ inputs.deploy-notifications-channel }}
timezone: ${{ inputs.timezone }}
include-default-facts: false # This cuts down on the message size for the prod room
custom-facts: ${{ steps.deployment-channel-facts.outputs.facts }}
custom-actions: ${{ inputs.custom-actions-for-deployment-notifications-channel }}