Skip to content

v1.277.0

v1.277.0 #23

name: Deploy to production
on:
release:
types: [published]
env:
hugo_image_cache_name: hugo-generated-images
hugo_image_cache_path: /home/runner/work/docs/docs/docs-repo/resources/_gen/images/
# This workflow builds the site with Hugo, syncs it over to the production web
# servers, and updates the production Algolia app to reflect the content in the
# new version of the site.
#
# The working directory for this GitHub Action is under:
# /home/runner/work/docs/docs/
#
# For this workflow, two repos are checked out:
# - The github.com/linode/docs repo is checked out into the `docs-repo` folder
# - The github.com/linode/linode-docs-theme repo is checked out into the
# `linode-docs-theme` folder.
#
# This workflow runs `hugo` to build the site inside the `docs-repo` folder.
# The site is rendered into the `docs-repo/public/` directory. The workflow
# rsyncs this folder is over to the destination web server.
#
# We check out the linode-docs-theme repo because it contains a
# `linode_algolia_admin` tool that we use to update the Algolia search indices.
#
# Inside the docs repo, the go.mod file contains a reference to which git
# commit of the linode-docs-theme is associated with the docs repo.
# We inspect this file to get that commit hash before checking out the
# linode-docs-theme repo.
#
# The following is a diagram of the above-mentioned repos and files. It does not
# show all the files within those repositories:
#
# .
#
# ├── docs-repo
# │   ├── go.mod
# │   └── public
# └── linode-docs-theme-repo
#    └── scripts
#       └── linode_algolia_admin
jobs:
deploy-to-production:
runs-on: ubuntu-latest
environment:
name: deploy_to_production
url: ${{ vars.DOCS_WEBSITE_URL }}
steps:
- name: Set up Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.116.1'
- name: Checkout docs repo
uses: actions/checkout@v3
with:
path: 'docs-repo'
# Debugging step so we can check if the right version
# of the docs repo is checked out
- name: Print current docs repo branch/ref/commit
working-directory: ./docs-repo
run: |
git status
git log -1
- name: Get linode-docs-theme version
id: get-theme-version
working-directory: ./docs-repo
run: |
# `hugo mod graph` prints output that looks like:
# project github.com/linode/linode-docs-theme@v0.0.0-20230706164309-cc2dbdeb7143+vendor
# In this example, cc2dbdeb7143 is the relevant commit hash for the
# linode-docs-theme repo. The following commands grab the commit hash
# from the `hugo mod graph` string
LINODE_DOCS_THEME_VERSION=$(hugo mod graph | grep linode-docs-theme | cut -d '+' -f 1 | grep -o '[^-]*$')
echo "VERSION=$LINODE_DOCS_THEME_VERSION" >> $GITHUB_OUTPUT
- name: Set up SSH agent (linode-docs-theme repo deploy key)
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.LINODE_DOCS_THEME_DEPLOY_KEY_FOR_DOCS_DEPLOY_GHA }}
- name: Checkout docs theme repo
run: |
git clone git@github.com:linode/linode-docs-theme linode-docs-theme-repo
- name: Check out theme repo commit from docs repo go.mod
working-directory: ./linode-docs-theme-repo
run: |
git checkout ${{ steps.get-theme-version.outputs.VERSION }}
# Debugging step so we can check if the right version
# of the Algolia admin tool is checked out
- name: Print Linode Algolia admin tool version
working-directory: ./linode-docs-theme-repo
run: |
cd scripts/linode_algolia_admin/
go run main.go version
# Debugging step that lists the Hugo-generated images
# directory *before* the imache cache restore step
- name: List contents of images dir
continue-on-error: true
run: ls -al ${{ env.hugo_image_cache_path }}
- name: Restore Hugo generated images cache
uses: ylemkimon/cache-restore@v2
with:
path: ${{ env.hugo_image_cache_path }}
key: ${{ env.hugo_image_cache_name }}
restore-keys: ${{ env.hugo_image_cache_name }}
# Debugging step that lists the Hugo-generated images
# directory *after* the imache cache restore step,
# to make sure that the restore happened successfully
- name: List contents of images dir
continue-on-error: true
run: ls -al ${{ env.hugo_image_cache_path }}
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 14
- name: Install dependencies (Node)
working-directory: ./docs-repo
run: npm ci
- name: Build Hugo
env:
HUGOxPARAMSxSEARCH_CONFIG2xAPP_ID: ${{ vars.ALGOLIA_APP_ID }}
HUGOxPARAMSxSEARCH_CONFIG2xAPI_KEY: ${{ vars.ALGOLIA_SEARCH_KEY }}
working-directory: ./docs-repo
run: |
hugo config
hugo -b "${{ vars.DOCS_WEBSITE_URL }}" --gc --minify -d public
# Debugging step that lists the Hugo-rendered files
# to make sure the site was built
- name: List rendered files
working-directory: ./docs-repo
run: |
sudo apt install -y tree
tree -L 1 public
# When Hugo builds, it renders search index data to a collection of
# data files under public/. This step uploads that data to the
# Algolia search backend
- name: Update Algolia
working-directory: ./linode-docs-theme-repo
env:
ALGOLIA_APP_ID: ${{ vars.ALGOLIA_APP_ID }}
ALGOLIA_ADMIN_API_KEY: ${{ secrets.ALGOLIA_WRITE_KEY }}
run: |
cd scripts/linode_algolia_admin/
# Hugo renders the site to the `public` directory within the docs repo.
# This includes three files with Algolia index data:
# - public/index.json
# - public/api/index.json
# - public/data/sections/index.json
# The pushdocs command uploads this data to Algolia
go run main.go pushdocs -source-dir ../../../docs-repo/public
# The settings (e.g. ranking configuration) and synonyms for the
# linode-merged index are stored in version control, and the
# following command pushes those settings/synonyms to the Algolia app
go run main.go -indices linode-merged push -replace settings,synonyms
# The refresh-merge-and-push sequence assumes that the linode-wp and linode-community indices already exist in the Algolia app
go run main.go sequence refresh-merge-and-push
# Why build Hugo twice? In order to render the Explore Docs nav menu,
# Hugo downloads data from the Algolia search backend. However, the
# first time we build Hugo in this workflow, that data isn't up-to-date
# with new content we may be publishing. So, we build Hugo a second time
# after we have performed the previous Update Algolia step.
# In summary:
# - Build Hugo the first time in order to render the JSON search index
# data files
# - Update Algolia with those data files
# - Build Hugo again so that the navigation UI can be rendered with that
# updated info from Algolia
# It's a little redundant, but solves the chicken-or-egg problem
- name: Build Hugo (second time)
env:
HUGOxPARAMSxSEARCH_CONFIG2xAPP_ID: ${{ vars.ALGOLIA_APP_ID }}
HUGOxPARAMSxSEARCH_CONFIG2xAPI_KEY: ${{ vars.ALGOLIA_SEARCH_KEY }}
working-directory: ./docs-repo
run: |
hugo config
hugo -b "${{ vars.DOCS_WEBSITE_URL }}" --gc --minify -d public
- name: Set up SSH agent (docs webserver key)
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.DOCS_WEBSITE_RSYNC_PRIVATE_KEY }}
- name: Rsync site to webserver
run: |
echo "${{ secrets.DOCS_WEBSITE_RSYNC_HOST_VERIFICATION_1 }}" > rsync_known_hosts
echo "${{ secrets.DOCS_WEBSITE_RSYNC_HOST_VERIFICATION_2 }}" >> rsync_known_hosts
rsync_to_destination() {
# Sync these assets without the --delete flag. These
# assets' filenames are fingerprinted, so they will not
# conflict with old versions that remain on the server.
rsync -r -e "ssh -o UserKnownHostsFile=rsync_known_hosts" \
docs-repo/public/css \
docs-repo/public/images \
docs-repo/public/js \
docs-repo/public/jslibs \
docs-repo/public/linode \
${{ secrets.DOCS_WEBSITE_USER }}@$1:${{ secrets.DOCS_WEBSITE_RSYNC_DIR }}
# Sync everything else, and delete files in the destination
# rsync dir that do not exist in the source docs-repo/public/
# folder
rsync -r -e "ssh -o UserKnownHostsFile=rsync_known_hosts" \
--exclude="/css/" \
--exclude="/images/" \
--exclude="/js/" \
--exclude="/jslibs/" \
--exclude="/linode/" \
--delete \
docs-repo/public/ \
${{ secrets.DOCS_WEBSITE_USER }}@$1:${{ secrets.DOCS_WEBSITE_RSYNC_DIR }}
}
rsync_to_destination "${{ secrets.DOCS_WEBSITE_RSYNC_DESTINATION_1 }}"
rsync_to_destination "${{ secrets.DOCS_WEBSITE_RSYNC_DESTINATION_2 }}"
rm rsync_known_hosts