Last active
May 31, 2024 21:19
-
-
Save lcatlett/b583d520408cfd70bd7734ef65f3ad94 to your computer and use it in GitHub Desktop.
Codeserver known host modificcation
This file contains hidden or 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: 'Reusable: Deploy code to configurable Pantheon environment' | |
on: | |
workflow_call: | |
inputs: | |
environment: | |
required: true | |
type: string | |
site_id: | |
type: string | |
clone: | |
type: boolean | |
backup: | |
type: boolean | |
secrets: | |
PANTHEON_DEVOPS_TOKEN: | |
required: true | |
DEVOPS_DRUPAL_USER: | |
required: true | |
DEVOPS_DRUPAL_PASSWORD: | |
required: true | |
CI_SSH_PRIVATE_KEY: | |
required: true | |
# Cancel previous runs of this same WF. | |
concurrency: | |
group: ci-deployment-${{ inputs.environment }} | |
cancel-in-progress: true | |
env: | |
# Need to set the secrets to env variables so we can interpolate the git string. | |
DEVOPS_DRUPAL_USER: ${{ secrets.DEVOPS_DRUPAL_USER }} | |
DEVOPS_DRUPAL_PASSWORD: ${{ secrets.DEVOPS_DRUPAL_PASSWORD }} | |
CI_SSH_PRIVATE_KEY: ${{ secrets.CI_SSH_PRIVATE_KEY }} | |
jobs: | |
environment_approval: | |
name: 'Acquire environment approval, if necessary' | |
# @todo How to handle if an environment passed is not defined? | |
environment: ${{ inputs.environment }} | |
runs-on: ubuntu-latest | |
steps: [run: echo 'Approved'] | |
publish_code: | |
name: 'Publish artifact to environment branch' | |
needs: [environment_approval] | |
runs-on: ubuntu-latest | |
outputs: | |
git: ${{ steps.blt_config.outputs.git }} | |
steps: | |
- uses: actions/checkout@v3 | |
with: | |
# @todo Is this always right? | |
ref: ${{ github.event.pull_request.head.sha }} | |
- name: Use Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: '18' | |
- name: 'Setup' | |
run: | | |
composer install -vvv | |
- name: 'Publish artifact to environment branch' | |
if: ${{ !contains(fromJson('["dev", "test", "live", "sync"]'), inputs.environment) }} | |
run: | | |
./vendor/bin/blt artifact:deploy --ignore-dirty --commit-msg "Automated commit (latest $GITHUB_REF_NAME) by Github for build $GITHUB_RUN_ID." --branch ${{ inputs.environment }} --no-interaction --verbose | |
- name: 'Get upstream git string' | |
id: blt_config | |
run : | | |
BLT_GIT_REMOTE=$(./vendor/bin/blt config:get git.remotes.0) | |
echo "git=$BLT_GIT_REMOTE" >> $GITHUB_OUTPUT | |
define_site_matrix: | |
uses: ./.github/workflows/call-matrix.yml | |
needs: [environment_approval] | |
secrets: inherit | |
with: | |
site_id: ${{ inputs.site_id }} | |
deploy_to_pantheon: | |
name: 'Deploy' | |
runs-on: ubuntu-latest | |
needs: | |
- publish_code | |
- define_site_matrix | |
strategy: | |
matrix: ${{ fromJson(needs.define_site_matrix.outputs.sites) }} | |
# Ensure all jobs get a chance to run. | |
fail-fast: false | |
env: | |
SITE_ID: ${{ matrix.site }} | |
CI_SSH_PRIVATE_KEY: ${{ secrets.CI_SSH_PRIVATE_KEY }} | |
steps: | |
- name: Install Terminus | |
uses: pantheon-systems/terminus-github-actions@v1 | |
with: | |
pantheon-machine-token: ${{ secrets.PANTHEON_DEVOPS_TOKEN }} | |
- name: 'Terminus authentication caching' | |
id: terminus-credentials-cache | |
uses: actions/cache/restore@v3 | |
with: | |
path: ~/.terminus | |
key: terminus-credentials-cache-${{ github.sha }} | |
- name: 'Terminus login' | |
if: steps.terminus-credentials-cache.outputs.cache-hit != 'true' | |
run: terminus auth:login --machine-token=${{ secrets.PANTHEON_DEVOPS_TOKEN }} | |
- name: Setup SSH | |
uses: webfactory/[email protected] | |
with: | |
ssh-private-key: ${{ secrets.CI_SSH_PRIVATE_KEY }} | |
- name: 'Push code to Pantheon' | |
env: | |
ENV_ID: ${{ inputs.environment }} | |
TASK_CLONE: ${{ inputs.clone }} | |
TASK_BACKUP: ${{ inputs.backup }} | |
UPSTREAM_GIT_URL: ${{ needs.publish_code.outputs.git }} | |
shell: bash | |
run: | | |
# Show commands run in output. | |
set -x | |
# Early exit? | |
if [[ -n $SITE_ID ]] && [[ -z $(terminus env:list $SITE_ID --field=id --filter='id='$ENV_ID) ]]; then | |
echo "::warning::Skipping $SITE_ID, no environment named $ENV_ID..." | |
exit 0; | |
fi | |
function push_code { | |
BRANCH=$ENV_ID | |
COMMIT_MSG="Automated commit (latest $GITHUB_REF_NAME) by Github for build $GITHUB_RUN_ID." | |
echo "Setting up SSH host keys for Pantheon site..." | |
# Default ENV_ID to dev | |
if [[ -z $ENV_ID ]]; then | |
ENV_ID="dev" | |
fi | |
SITE_UUID=$(terminus site:lookup "$SITE_ID") | |
ssh-keyscan -t rsa -p 2222 "appserver.${ENV_ID}.${SITE_UUID}.drush.in" >>~/.ssh/known_hosts | |
ssh-keyscan -t rsa -p 2222 "codeserver.dev.${SITE_UUID}.drush.in" >>~/.ssh/known_hosts | |
# Clone the artifact. | |
mkdir $RUNNER_TEMP/upstream | |
cd $RUNNER_TEMP/upstream | |
git clone --branch $ENV_ID --depth 2 ${{ env.UPSTREAM_GIT_URL }} . | |
SITE_GIT_URL=$(terminus connection:info $SITE_ID.$ENV_ID --field=git_url) | |
mkdir $RUNNER_TEMP/$SITE_ID | |
cd $RUNNER_TEMP/$SITE_ID | |
# Initialize git. | |
git init --quiet | |
git config --local user.name "Github Actions CI" | |
git config --local user.email "[email protected]" | |
# @todo Below 2 directives needed? | |
git config --local core.excludesfile false | |
git config --local core.fileMode true | |
git remote add pantheon $SITE_GIT_URL | |
git checkout -b $BRANCH | |
# If the branch exists, merge it. | |
# NOTE: This is a fuzzy match. So "master" matches "master" and "test/master". | |
if git ls-remote pantheon $ENV_ID | wc -l > /dev/null; then | |
echo 'Pulling existing branch...' | |
GIT_SSH_COMMAND="ssh -vvv" git fetch pantheon $BRANCH --depth=1 -vv | |
git merge pantheon/$BRANCH -vv | |
fi | |
# Rsync files from the artifact, delete any files not present in the artifact, but dont send .git/ or .github/ folders, and protect the destination .git/ folder. | |
rsync -a --no-g --delete --delete-excluded --exclude='.git/' --exclude='.github/' --filter 'protect /.git/' $RUNNER_TEMP/upstream/ ./ | |
# This is what BLT DeployCommand is doing. | |
git rm -r --cached --ignore-unmatch --quiet . | |
git add -A | |
git commit -m "$COMMIT_MSG" --quiet --allow-empty | |
echo "Pushing artifact to Pantheon $ENV_ID" | |
git push pantheon $BRANCH -vv | |
} | |
function pull_code { | |
if [[ "$ENV_ID" =~ ^(dev|sync)$ ]]; then | |
# Pull code updates from custom upstream master branch. | |
terminus upstream:updates:apply --accept-upstream --yes -- $SITE_ID.$ENV_ID | |
elif [[ "$ENV_ID" =~ ^(test|live)$ ]]; then | |
terminus env:deploy --yes -- $SITE_ID.$ENV_ID | |
else | |
echo "::warning::Function pull_code called, but for an invalid environment..." | |
fi | |
} | |
function code_update { | |
# Wait while code gets deployed to Pantheon servers. | |
terminus workflow:wait $SITE_ID.$ENV_ID -vvv | |
# Testing additional wait... | |
sleep 30 | |
terminus drush $SITE_ID.$ENV_ID -- updatedb -n -vvv | |
terminus drush $SITE_ID.$ENV_ID -- cache:rebuild -vvv | |
} | |
# Wake the environment up, if it's needed... | |
terminus env:wake $SITE_ID.$ENV_ID -vvv | |
# @todo This currently doesn't work, but we need to wait for it. | |
# Only wait 20 seconds max for the environment to wake up. | |
terminus workflow:wait --max=20 $SITE_ID.$ENV_ID -vvv | |
if [ "$TASK_CLONE" = true ]; then | |
# Check if LIVE environment exists. | |
if [[ -n $(terminus env:list $SITE_ID --field=id --filter='id=live') ]]; then | |
terminus env:clone-content --yes -- $SITE_ID.live $ENV_ID | |
else | |
echo "::warning::Site $SITE_ID not cloned, no LIVE environment..." | |
fi | |
fi | |
if [ "$TASK_BACKUP" = true ]; then | |
terminus backup:create -- $SITE_ID.$ENV_ID | |
fi | |
if [[ "$ENV_ID" =~ ^(dev|test|live|sync)$ ]]; then | |
# Pantheon pipeline. Expects custom upstream `master` is up to date. | |
pull_code | |
else | |
# Multidev. Must push code. | |
push_code | |
fi | |
code_update | |
- name: 'Terminus logout' | |
if: always() | |
run: terminus auth:logout | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment