Skip to content

Commit

Permalink
Merge pull request #1618 from danskernesdigitalebibliotek/lagoon-gh-d…
Browse files Browse the repository at this point in the history
…eployment

Optimizing GH actions, to use less minutes.
  • Loading branch information
rasben authored Oct 9, 2024
2 parents 76f92cd + 5b2991d commit e74fc63
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 96 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ env:
PHP_VERSION: 8.1
COMPOSER_VERSION: v2

# Detect if this action is already running, and cancel it.
# This most likely happened because a second push has been made to a branch.
concurrency:
group: ${{ github.repository_id }}-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
ValidateComposer:
name: Validate Composer
Expand Down
120 changes: 30 additions & 90 deletions .github/workflows/lagoon.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
on:
pull_request:
# We have two groups of jobs in this workflow that reacts on actions:
#
# 1. We update the status of a Github Deployment on:
# - opened
# - synchronize
# - reopened
# - closed
#
# 2. We forward all events to lagoon via InformLagoon
types: [ opened, synchronize, reopened, closed, edited ]
name: Lagoon integration

env:
LAGOON_HOST: "dplplat01.dpl.reload.dk"
LAGOON_PROJECT: "dpl-cms"

LAGOON_ENVIRONMENT: "pr-${{github.event.number}}"
GH_TOKEN: ${{ secrets.GH_DEPLOYMENT_TOKEN }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
jobs:
BranchNameLength:
name: Check branch length
Expand All @@ -31,100 +23,48 @@ jobs:
/^.{1,100}$/
errorMessage: 'Branch name too long. This cannot be deployed to Lagoon.'

CheckEnvironment:
name: Check environment
# Creating the deployment that Lagoon will look for, and add status to.
CreateDeployment:
name: Creating deployment
runs-on: ubuntu-latest
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }}
needs: [BranchNameLength]
permissions:
# Give the default GITHUB_TOKEN permission to create and update deployments
deployments: write
if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' }}
steps:
- name: Generate environment data
id: environment
run: |
echo ::set-output name=id::pr-${{github.event.number}}
echo ::set-output name=url::'https://varnish.pr-${{github.event.number}}.${{ env.LAGOON_PROJECT }}.${{ env.LAGOON_HOST }}/'
echo ::set-output name=logs::'https://ui.lagoon.${{ env.LAGOON_HOST }}/projects/${{ env.LAGOON_PROJECT }}/${{ env.LAGOON_PROJECT }}-pr-${{github.event.number}}/deployments'
- name: Start deployment
uses: bobheadxi/[email protected]
id: deployment
with:
step: start
token: ${{ secrets.GITHUB_TOKEN }}
env: ${{ steps.environment.outputs.id }}
ref: ${{ github.head_ref }}
logs: ${{ steps.environment.outputs.logs }}
debug: ${{ runner.debug && 'true' || 'false' }}
- name: Generate wait-on config
# Retrieval of Let's Encrypt certificate sometimes fail in Lagoon.
# In this case a self-signed certificate will be used. Allow this.
run: |
echo "{\"strictSSL\": false}" > $RUNNER_TEMP/wait-on.config.json
- name: Wait for environment to become available
uses: iFaxity/[email protected]
with:
resource: ${{ steps.environment.outputs.url }}
# Time in ms. Wait for 20 mins for deployment to complete. We have
# seen deployments taking up to 17 mins.
timeout: 1200000
# Poll every 10 seconds. For whatever reason Lagoon environments may
# return 200 during the deployment process even though the deployment
# is not complete. Reduce polling interval to the risk of this
# happening.
interval: 10000
config: ${{ runner.temp }}/wait-on.config.json
- name: Finish deployment
if: always()
uses: bobheadxi/[email protected]
with:
step: finish
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
env: ${{ steps.deployment.outputs.env }}
env_url: ${{ steps.environment.outputs.url }}
logs: ${{ steps.environment.outputs.logs }}
debug: ${{ runner.debug && 'true' || 'false' }}
- run: |
LAGOON_DEPLOYS_LOG_URL=$(echo "https://ui.lagoon.dplplat01.dpl.reload.dk/projects/dpl-cms/dpl-cms-${{ env.LAGOON_ENVIRONMENT }}/deployments")
DEPLOYMENT_ID=$(echo '{
"ref": "${{ github.head_ref || github.ref_name }}",
"environment": "${{ env.LAGOON_ENVIRONMENT }}",
"auto_merge": false,
"required_contexts": []
}' | gh api --method POST "/repos/${{ env.OWNER }}/${{ env.REPO }}/deployments" --input - --jq '.id')
gh api --method POST "/repos/${{ env.OWNER }}/${{ env.REPO }}/deployments/$DEPLOYMENT_ID/statuses" \
-f "state=in_progress" -f "log_url=$LAGOON_DEPLOYS_LOG_URL"
echo "deployment_id=$DEPLOYMENT_ID" >> $GITHUB_OUTPUT
# When we close the pull request, we want to set the environment as inactive.
CloseEnvironment:
name: Close environment
runs-on: ubuntu-latest
if: ${{ github.event.action == 'closed' }}
permissions:
# Give the default GITHUB_TOKEN permission to close deployments.
deployments: write
steps:
- name: Generate environment data
id: environment
run: |
echo ::set-output name=id::pr-${{github.event.number}}
- name: Close environment
uses: bobheadxi/[email protected]
with:
step: deactivate-env
token: ${{ secrets.GITHUB_TOKEN }}
env: ${{ steps.environment.outputs.id }}
debug: ${{ runner.debug && 'true' || 'false' }}
- run: gh api --method DELETE "/repos/${{ env.OWNER }}/${{ env.REPO }}/environments/${{ env.LAGOON_ENVIRONMENT }}"

# We only permit the integration with Lagoon to run if the user is
# authorized. This saves on resources and ensures we only spin up sites for
# legitimate contributions.
# The integration is controlled by creating synthetic events related to select
# pull-request events, and send them to Lagoon.
#
# The job expects the following secrets:
# LAGOON_WEBHOOK_URL: The url events are to be delivered to
# LAGOON_WEBHOOK_SECRET: Shared lagoon webhook secret
#
InformLagoon:
name: Send synthetic event to Lagoon
runs-on: ubuntu-latest
needs: [BranchNameLength]
steps:
- name: Send pull request event
uses: distributhor/workflow-webhook@v3
env:
webhook_url: ${{ secrets.LAGOON_WEBHOOK_URL }}
webhook_secret: ${{ secrets.LAGOON_WEBHOOK_SECRET }}
webhook_type: 'json-extended'
- name: Send pull request event
uses: distributhor/workflow-webhook@v3
env:
webhook_url: ${{ secrets.LAGOON_WEBHOOK_URL }}
webhook_secret: ${{ secrets.LAGOON_WEBHOOK_SECRET }}
webhook_type: 'json-extended'
47 changes: 41 additions & 6 deletions .lagoon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,36 @@ project: dpl-cms-core

ssh: 20.238.147.183:22
api: https://api.lagoon.dplplat01.dpl.reload.dk/graphql
environment_variables:
git_sha: 'true'

tasks:
post-rollout:
- run:
name: Create new GH deployment
command: |
GH_DEPLOYMENTS=$(curl -H "Authorization: Bearer $GH_DEPLOYMENT_TOKEN" \
"https://api.github.com/repos/danskernesdigitalebibliotek/dpl-cms/deployments?ref=$LAGOON_PR_HEAD_BRANCH&environment=$LAGOON_ENVIRONMENT")
GH_DEPLOYMENT_ID=$(echo "$GH_DEPLOYMENTS" | grep '"id":' | head -n 1 | sed 's/[^0-9]*\([0-9]*\).*/\1/')
echo "$GH_DEPLOYMENTS"
echo "Found GH deployment with ID '$GH_DEPLOYMENT_ID'"
# The only way to keep a value between tasks, is saving it in a
# file. Environment variables are killed between tasks, apart from
# the global ones.
echo "$GH_DEPLOYMENT_ID" > /tmp/GH_DEPLOYMENT_ID
LAGOON_DEPLOYS_LOG_URL="https://ui.lagoon.dplplat01.dpl.reload.dk/projects/$LAGOON_PROJECT/dpl-cms-$LAGOON_ENVIRONMENT/deployments"
echo "$LAGOON_DEPLOYS_LOG_URL" > /tmp/LAGOON_DEPLOYS_LOG_URL
echo "Creating a initial pending deployment status."
./dev-scripts/lagoon-set-gh-deploy-status.sh "in_progress"
service: cli
- run:
name: If drupal is not installed
command: |
set -e
source dev-scripts/lagoon-error-handling.sh
if tables=$(drush sqlq "show tables like 'node';") && [ -z "$tables" ]; then
# Install and set the admin password to a Lagoon variable if it exists.
if [[ -n $PR_DRUPAL_PWD ]]; then
Expand All @@ -29,7 +52,8 @@ tasks:
- run:
name: drush deploy
command: |
set -e
source dev-scripts/lagoon-error-handling.sh
if [[ -f config/sync/system.site.yml ]]; then
echo "Config detected, doing a drush deploy"
drush deploy
Expand All @@ -49,7 +73,8 @@ tasks:
# it will be gone.
name: Create module upload directory in public files
command: |
set -e
source dev-scripts/lagoon-error-handling.sh
if [[ ! -d "web/sites/default/files/modules_local" ]]; then
echo "Creating directory for module uploads"
mkdir web/sites/default/files/modules_local
Expand All @@ -58,14 +83,16 @@ tasks:
- run:
name: Import translations
command: |
set -e;
source dev-scripts/lagoon-error-handling.sh
drush locale-check
drush locale-update
service: cli
- run:
name: Create test users
command: |
set -e
source dev-scripts/lagoon-error-handling.sh
# Only create test users if they do not exist already.
if editor_user=$(drush sqlq 'select * from users_field_data where name = "editor"') && [ -z "$editor_user" ]; then
drush user:create editor --password="$PR_DRUPAL_PWD"
Expand All @@ -89,9 +116,17 @@ tasks:
- run:
name: Enable example content
command: |
set -e
source dev-scripts/lagoon-error-handling.sh
drush en -y dpl_example_content
service: cli
- run:
name: Setting Deployment status success
command: |
DRUPAL_URL=$(drush browse)
./dev-scripts/lagoon-set-gh-deploy-status.sh "success" "$DRUPAL_URL"
service: cli

environments:
main:
Expand Down
15 changes: 15 additions & 0 deletions dev-scripts/lagoon-error-handling.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# This error handler is used in .lagoon.yml, for catching errors and passing
# along the failing details to the GH deployment.

error_handler() {
./dev-scripts/lagoon-set-gh-deploy-status.sh "failure"

# As we've gotten rid of set -e in lagoon.yml, it is very important to exit
# here, otherwise, lagoon will think a faulty deploy has succeeded.
exit "$1"
}

# Set up trap for ERR signal
trap 'error_handler $?' ERR
22 changes: 22 additions & 0 deletions dev-scripts/lagoon-set-gh-deploy-status.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

# Ensure the required arguments are passed
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "Usage: $0 <state> [optional_environment_url]"
exit 1
fi

# Assign the state passed as an argument
STATE=$1
DRUPAL_URL=${2:-""}

GH_DEPLOYMENT_ID=$(cat /tmp/GH_DEPLOYMENT_ID)
LAGOON_DEPLOYS_LOG_URL=$(cat /tmp/LAGOON_DEPLOYS_LOG_URL)

echo "Setting GH deployment status '$GH_DEPLOYMENT_ID': '$STATE'"

# GitHub API request to update deployment status
curl -L -X POST -H "Authorization: Bearer $GH_DEPLOYMENT_TOKEN" \
"https://api.github.com/repos/danskernesdigitalebibliotek/dpl-cms/deployments/$GH_DEPLOYMENT_ID/statuses" \
-d "{\"environment\":\"$LAGOON_ENVIRONMENT\",\"state\":\"$STATE\", \
\"environment_url\":\"$DRUPAL_URL\", \"log_url\":\"$LAGOON_DEPLOYS_LOG_URL\"}"

0 comments on commit e74fc63

Please sign in to comment.