build main #509
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
--- | |
name: build main | |
# Actions that take place after every commit the master/main branch. | |
# Here every commit is built, tagged as 'latest' and tested. | |
# If a DOCKERHUB_USERNAME secret is defined the image is pushed. | |
# If a TRIGGER_AWX secret is defined the image is deployed to Kubernetes. | |
# Actions also run if the repository is tagged. | |
# Every tag is deployed to staging and every production-grade tag | |
# (of the form N.N.N) is deployed to production.defaults: | |
# | |
# Actions also run on a schedule - the container is built, tested, | |
# pushed and deployed (if the relevant secrets are set) based on | |
# a defined schedule. | |
# | |
# Actions also run on external trigger (workflow-dispatch). | |
# --------------- | |
# Control secrets | |
# --------------- | |
# | |
# At the GitHub 'organisation' or 'project' level you are expected to | |
# have the following GitHub 'Repository Secrets' defined | |
# (i.e. via 'Settings -> Secrets'): - | |
# | |
# BE_IMAGE_TAG optional - default stable | |
# BE_NAMESPACE optional - default xchem | |
# FE_BRANCH optional - default production | |
# FE_NAMESPACE optional - default xchem | |
# STACK_NAMESPACE optional - default xchem | |
# | |
# DOCKERHUB_USERNAME optional | |
# DOCKERHUB_TOKEN optional - required if DOCKERHUB_USERNAME | |
# | |
# TRIGGER_AWX optional - set to 'yes' to deploy 'official' builds via AWX | |
# you also need to define the repository environments | |
# 'awx/fragalysis-staging' and 'awx/fragalysis-production'. | |
# You should not set this and TRIGGER_DEVELOPER_AWX. | |
# TRIGGER_DEVELOPER_AWX optional - set to 'yes' to deploy a developer-specific build via AWX | |
# you also need to set the repository environment | |
# 'awx/fragalysis-developer'. | |
# You should not set this and TRIGGER_AWX. | |
# | |
# SLACK_NOTIFY_WEBHOOK optional - required for Slack notifications | |
# | |
# ----------- | |
# Environment (GitHub Environments) | |
# ----------- | |
# | |
# Environment awx/fragalysis-staging | |
# Environment awx/fragalysis-production | |
# Environment awx/fragalysis-developer | |
# | |
# For automated deployment we expect the following in the environment: - | |
# | |
# AWX_HOST The fully-qualified URL to AWX. | |
# If not set, AWX triggering does not take place. | |
# AWX_USER The username of someone that can execute the AWX Job. | |
# AWX_USER_PASSWORD The user's password. | |
# AWX_TEMPLATE_NAME The template to run (for developer environments) | |
on: | |
push: | |
branches: | |
- 'master' | |
- 'main' | |
tags: | |
- '**' | |
# Build if triggered externally. | |
# The trigger can provide a number of (optional) inputs... | |
workflow_dispatch: | |
inputs: | |
be_namespace: | |
description: The fragalysis-backend namespace (to pull from) | |
required: false | |
be_image_tag: | |
description: The fragalysis-backend image container tag (to pull from) | |
required: false | |
fe_namespace: | |
description: The fragalysis-frontend namespace (to clone from) | |
required: false | |
fe_branch: | |
description: The fragalysis-frontend branch (to clone from) | |
required: false | |
stack_namespace: | |
description: The fragalysis-stack Docker Hub namespace (to publish to) | |
required: false | |
stack_image_tag: | |
description: The image tage to apply to the fragalysis-stack image | |
required: false | |
env: | |
# The following 'defaults' are used in the 'Initialise workflow variables' step, | |
# which creates 'outputs' for use in steps and jobs that follow it. | |
# The values set here are used unless a matching secret is found. | |
# Secrets are the way users dynamically control the behaviour of this Action. | |
# | |
# For Jobs conditional on the presence of a secret see this Gist... | |
# https://gist.github.com/jonico/24ffebee6d2fa2e679389fac8aef50a3 | |
# | |
# New production stack builds should always result in a change to one | |
# or both of the Backend or Frontend tags. i.e. before we make a production | |
# release the author needs to change one or both of: - | |
# | |
# - BE_IMAGE_TAG | |
# - FE_BRANCH | |
# | |
# | |
# Commit the changes and then tag or make a release from the stack repository. | |
BE_IMAGE_TAG: 2023.07.1 | |
FE_BRANCH: 2023.05.1 | |
BE_NAMESPACE: xchem | |
FE_NAMESPACE: xchem | |
STACK_NAMESPACE: xchem | |
# Common slack notification variables. | |
# Used in the rtCamp/action-slack-notify Action. | |
SLACK_USERNAME: ActionBot | |
SLACK_ICON: https://github.com/InformaticsMatters/dls-fragalysis-stack-kubernetes/raw/master/icons/094-robot-face-3-512.png?size=48 | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
outputs: | |
deploy: ${{ steps.vars.outputs.deploy }} | |
deploy-developer: ${{ steps.vars.outputs.deploy-developer }} | |
production-tag: ${{ steps.vars.outputs.production-tag }} | |
push: ${{ steps.vars.outputs.push }} | |
tag: ${{ steps.vars.outputs.tag }} | |
version: ${{ steps.vars.outputs.version }} | |
steps: | |
- name: Inject slug/short variables | |
uses: rlespinasse/[email protected] | |
- name: Initialise workflow variables | |
id: vars | |
env: | |
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} | |
SLACK_NOTIFY_WEBHOOK: ${{ secrets.SLACK_NOTIFY_WEBHOOK }} | |
TRIGGER_AWX: ${{ secrets.TRIGGER_AWX }} | |
TRIGGER_DEVELOPER_AWX: ${{ secrets.TRIGGER_DEVELOPER_AWX }} | |
run: | | |
# BE_NAMESPACE | |
BE_NAMESPACE="${{ env.BE_NAMESPACE }}" | |
if [ -n "${{ github.event.inputs.be_namespace }}" ]; then BE_NAMESPACE="${{ github.event.inputs.be_namespace }}"; | |
elif [ -n "${{ secrets.BE_NAMESPACE }}" ]; then BE_NAMESPACE="${{ secrets.BE_NAMESPACE }}"; fi | |
echo set-output name=BE_NAMESPACE::${BE_NAMESPACE} | |
echo ::set-output name=BE_NAMESPACE::${BE_NAMESPACE} | |
# BE_IMAGE_TAG | |
BE_IMAGE_TAG="${{ env.BE_IMAGE_TAG }}" | |
if [ -n "${{ github.event.inputs.be_image_tag }}" ]; then BE_IMAGE_TAG="${{ github.event.inputs.be_image_tag }}"; | |
elif [ -n "${{ secrets.BE_IMAGE_TAG }}" ]; then BE_IMAGE_TAG="${{ secrets.BE_IMAGE_TAG }}"; fi | |
echo set-output name=BE_IMAGE_TAG::${BE_IMAGE_TAG} | |
echo ::set-output name=BE_IMAGE_TAG::${BE_IMAGE_TAG} | |
# FE_NAMESPACE | |
FE_NAMESPACE="${{ env.FE_NAMESPACE }}" | |
if [ -n "${{ github.event.inputs.fe_namespace }}" ]; then FE_NAMESPACE="${{ github.event.inputs.fe_namespace }}"; | |
elif [ -n "${{ secrets.FE_NAMESPACE }}" ]; then FE_NAMESPACE="${{ secrets.FE_NAMESPACE }}"; fi | |
echo set-output name=FE_NAMESPACE::${FE_NAMESPACE} | |
echo ::set-output name=FE_NAMESPACE::${FE_NAMESPACE} | |
# FE_BRANCH | |
FE_BRANCH="${{ env.FE_BRANCH }}" | |
if [ -n "${{ github.event.inputs.fe_branch }}" ]; then FE_BRANCH="${{ github.event.inputs.fe_branch }}"; | |
elif [ -n "${{ secrets.FE_BRANCH }}" ]; then FE_BRANCH="${{ secrets.FE_BRANCH }}"; fi | |
echo set-output name=FE_BRANCH::${FE_BRANCH} | |
echo ::set-output name=FE_BRANCH::${FE_BRANCH} | |
# STACK_NAMESPACE | |
STACK_NAMESPACE="${{ env.STACK_NAMESPACE }}" | |
if [ -n "${{ github.event.inputs.stack_namespace }}" ]; then STACK_NAMESPACE="${{ github.event.inputs.stack_namespace }}"; | |
elif [ -n "${{ secrets.STACK_NAMESPACE }}" ]; then STACK_NAMESPACE="${{ secrets.STACK_NAMESPACE }}"; fi | |
echo set-output name=STACK_NAMESPACE::${STACK_NAMESPACE} | |
echo ::set-output name=STACK_NAMESPACE::${STACK_NAMESPACE} | |
# Set a version | |
STACK_VERSION="0.0.0" | |
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then STACK_VERSION="${{ env.GITHUB_REF_SLUG }}"; | |
else STACK_VERSION="${{ github.ref_name }}.${{ github.run_number }}"; fi | |
echo set-output name=STACK_VERSION::${STACK_VERSION} | |
echo ::set-output name=STACK_VERSION::${STACK_VERSION} | |
# What image tag are we creating? 'latest' (if not tagged) or a GitHub tag? | |
TAG="latest" | |
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then TAG="${{ env.GITHUB_REF_SLUG }}"; fi | |
echo set-output name=tag::${TAG} | |
echo ::set-output name=tag::${TAG} | |
# Do we push, i.e. is DOCKERHUB_USERNAME defined? | |
echo set-output name=push::${{ env.DOCKERHUB_USERNAME != '' }} | |
echo ::set-output name=push::${{ env.DOCKERHUB_USERNAME != '' }} | |
# Do we deploy official images, i.e. is TRIGGER_AWX 'yes'? | |
echo set-output name=deploy::${{ env.TRIGGER_AWX == 'yes' }} | |
echo ::set-output name=deploy::${{ env.TRIGGER_AWX == 'yes' }} | |
# Do we deploy developer images, i.e. is TRIGGER_DEVELOPER_AWX 'yes'? | |
echo set-output name=deploy-developer::${{ env.TRIGGER_DEVELOPER_AWX == 'yes' }} | |
echo ::set-output name=deploy-developer::${{ env.TRIGGER_DEVELOPER_AWX == 'yes' }} | |
# Do we deploy to production, i.e. is there a TAG of the form N.N.N? | |
HAS_PRODUCTION_TAG=false | |
if [[ ${{ env.GITHUB_REF_SLUG }} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then HAS_PRODUCTION_TAG=true; fi | |
echo set-output name=production-tag::${HAS_PRODUCTION_TAG} | |
echo ::set-output name=production-tag::${HAS_PRODUCTION_TAG} | |
# Do we send Slack notifications, i.e. is SLACK_NOTIFY_WEBHOOK defined? | |
echo set-output name=notify::${{ env.SLACK_NOTIFY_WEBHOOK != '' }} | |
echo ::set-output name=notify::${{ env.SLACK_NOTIFY_WEBHOOK != '' }} | |
- name: Checkout | |
uses: actions/checkout@v2 | |
- name: Display build args | |
run: | | |
echo BE_NAMESPACE=${{ steps.vars.outputs.BE_NAMESPACE }} | |
echo BE_IMAGE_TAG=${{ steps.vars.outputs.BE_IMAGE_TAG }} | |
echo FE_NAMESPACE=${{ steps.vars.outputs.FE_NAMESPACE }} | |
echo FE_BRANCH=${{ steps.vars.outputs.FE_BRANCH }} | |
echo STACK_NAMESPACE=${{ steps.vars.outputs.STACK_NAMESPACE }} | |
echo STACK_VERSION=${{ steps.vars.outputs.STACK_VERSION }} | |
echo tag=${{ steps.vars.outputs.tag }} | |
- name: Build | |
uses: docker/build-push-action@v2 | |
with: | |
tags: ${{ steps.vars.outputs.STACK_NAMESPACE }}/fragalysis-stack:${{ steps.vars.outputs.tag }} | |
build-args: | | |
BE_NAMESPACE=${{ steps.vars.outputs.BE_NAMESPACE }} | |
BE_IMAGE_TAG=${{ steps.vars.outputs.BE_IMAGE_TAG }} | |
FE_NAMESPACE=${{ steps.vars.outputs.FE_NAMESPACE }} | |
FE_BRANCH=${{ steps.vars.outputs.FE_BRANCH }} | |
STACK_NAMESPACE=${{ steps.vars.outputs.STACK_NAMESPACE }} | |
STACK_VERSION=${{ steps.vars.outputs.tag }} | |
- name: Test | |
run: > | |
docker-compose -f docker-compose.test.yml up | |
--exit-code-from tests | |
--abort-on-container-exit | |
env: | |
STACK_NAMESPACE: ${{ steps.vars.outputs.STACK_NAMESPACE }} | |
STACK_TAG: ${{ steps.vars.outputs.tag }} | |
- name: Login to DockerHub | |
if: steps.vars.outputs.push == 'true' | |
uses: docker/login-action@v1 | |
with: | |
username: ${{ secrets.DOCKERHUB_USERNAME }} | |
password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Push | |
if: steps.vars.outputs.push == 'true' | |
run: docker push ${{ steps.vars.outputs.STACK_NAMESPACE }}/fragalysis-stack:${{ steps.vars.outputs.tag }} | |
- name: Notify build | |
if: steps.vars.outputs.notify == 'true' | |
uses: rtCamp/action-slack-notify@v2 | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFY_WEBHOOK }} | |
SLACK_TITLE: Build Complete | |
SLACK_MESSAGE: Built image ${{ steps.vars.outputs.STACK_NAMESPACE }}/fragalysis-stack:${{ steps.vars.outputs.tag }} | |
deploy-staging: | |
# A fixed job that "deploys to the Fragalysis Staging" Kubernetes Namespace | |
# using a pre-defined AWX Job Template name | |
# and the awx/fragalysis-production environment. | |
# | |
# All builds, tagged or otherwise, are deployed to staging. | |
needs: build | |
if: | | |
needs.build.outputs.push == 'true' && | |
needs.build.outputs.deploy == 'true' | |
runs-on: ubuntu-latest | |
environment: awx/fragalysis-production | |
steps: | |
- name: Deploy staging | |
uses: informaticsmatters/trigger-awx-action@v1 | |
with: | |
template: Staging Fragalysis Stack (Version Change) | |
template-host: ${{ secrets.AWX_HOST }} | |
template-user: ${{ secrets.AWX_USER }} | |
template-user-password: ${{ secrets.AWX_USER_PASSWORD }} | |
template-var: stack_image_tag | |
template-var-value: ${{ needs.build.outputs.tag }} | |
- name: Notify staging deployment | |
if: steps.vars.outputs.notify == 'true' | |
uses: rtCamp/action-slack-notify@v2 | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFY_WEBHOOK }} | |
SLACK_TITLE: Deployment Complete (Staging) | |
SLACK_MESSAGE: Deployed ${{ needs.build.outputs.tag }} | |
deploy-production: | |
# A fixed job that "deploys to the Fragalysis Production" Kubernetes Namespace | |
# using a pre-defined AWX Job Template name | |
# and the awx/fragalysis-production environment. | |
# | |
# Only builds triggered by production-grade tags are deployed to production. | |
needs: build | |
if: | | |
needs.build.outputs.push == 'true' && | |
needs.build.outputs.deploy == 'true' && | |
needs.build.outputs.production-tag == 'true' | |
runs-on: ubuntu-latest | |
environment: awx/fragalysis-production | |
steps: | |
- name: Deploy production | |
uses: informaticsmatters/trigger-awx-action@v1 | |
with: | |
template: Production Fragalysis Stack (Version Change) | |
template-host: ${{ secrets.AWX_HOST }} | |
template-user: ${{ secrets.AWX_USER }} | |
template-user-password: ${{ secrets.AWX_USER_PASSWORD }} | |
template-var: stack_image_tag | |
template-var-value: ${{ needs.build.outputs.tag }} | |
- name: Notify production deployment | |
if: steps.vars.outputs.notify == 'true' | |
uses: rtCamp/action-slack-notify@v2 | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFY_WEBHOOK }} | |
SLACK_TITLE: Deployment Complete (Production) | |
SLACK_MESSAGE: Deployed ${{ needs.build.outputs.tag }} | |
deploy-developer: | |
# A "deploy to a developer's Fragalysis" Kubernetes Namespace | |
# using an environment-defined AWX Job Template name | |
# and the awx/fragalysis-developer environment. | |
needs: build | |
if: | | |
needs.build.outputs.push == 'true' && | |
needs.build.outputs.deploy-developer == 'true' | |
runs-on: ubuntu-latest | |
environment: awx/fragalysis-developer | |
steps: | |
- name: Deploy developer | |
uses: informaticsmatters/trigger-awx-action@v1 | |
with: | |
template: ${{ secrets.AWX_TEMPLATE_NAME }} | |
template-host: ${{ secrets.AWX_HOST }} | |
template-user: ${{ secrets.AWX_USER }} | |
template-user-password: ${{ secrets.AWX_USER_PASSWORD }} | |
template-var: stack_image_tag | |
template-var-value: ${{ needs.build.outputs.tag }} |