Skip to content

Instantly share code, notes, and snippets.

@johnallen3d
Last active September 8, 2021 18:20
Show Gist options
  • Save johnallen3d/38f750fcf5085ff5ad2d30afbc9b8d05 to your computer and use it in GitHub Desktop.
Save johnallen3d/38f750fcf5085ff5ad2d30afbc9b8d05 to your computer and use it in GitHub Desktop.
Config Deployment

Every PR

  • If the PR is not for a maintenance issue or an external dependency then add a CHANGELOG entry

Production Releases

  • Update CHANGELOG

    • Create a new release header, example: ## Release PR #608 (2020-09-15)

    • Add this just below "When submitting a new PR..."

    • Remove headers that do not have elements (i.e. "### Deprecated")

    • Recreate header placeholders

      ### Added
      
      ### Changed
      
      ### Deprecated
      
      ### Removed
      
      ### Fixed
      
      ### Security
  • Create a release PR master -> env/production

    git checkout master
    git pull
    
    gh pr create \
      --base env/production \
      --label release \
      --project Incent \
      --title "Production Deployment" \
      --body "$(date "+%Y-%m-%d") Production Deployment
  • Follow standard review/approval process

  • Once approval has been received from all reviewers merge the PR using the "Create a merge commit" option. DO NOT SQUASH AND MERGE or REBASE AND MERGE!!!

  • Tag the release

    release_pr_number="nnn"
    
    git checkout env/production
    git pull
    
    today=$(date "+%Y-%m-%d")
    annotation="$today/$release_pr_number"
    message="Release PR #$release_pr_number ($today)"
    
    git tag \
        --annotate "$annotation" \
        --message "$message"
    
    git push --tags
  • Edit tag and copy the contents of the release section from CHANGELOG https://github.com/technekes/incent-api/tags

Config Deployment

Deployment process

Setup

Place the contents of deployments.sh in the directory above config directories.

Deployment

Start up a terminal and switch to the appropriate config directory.

cd /path/to/config/incent-config-[client-key]

Start a bash shell (if not already using bash).

bash

Source the deployments shell file with utility functions.

source ../deployment.sh

Set a variable for the program-set key we will be deploying.

program_set=[program-set-key]

Set a variable for the zoho ticket id (if applicable; the long id in url).

ticket=[long-id-from-url]

If GitHub issue doesn't exist (e.g. no ZOHO ticket because n/a program-set).

create_issue $program_set

Set a variable for the GitHub issue number related to this deployment.

issue=[issue-number]

Create a branch for the release.

create_release_branch

NOTE -- When the branch is created it will include the date and a "counter" (e.g. 2020-10-01/01). The counter here is hard-coded. If you are doing a second release for a program-set on a particular day you will want to rename the branch.

As an example (not to be copy and pasted). Note the final character has been incremented.

git branch -m release/2020-foo-bar/2020-10-01/02

This command, after creating a branch from master will print out a "best guess" of commits on config-changes that are not yet on master. This list will like include commits that have already landed, it's intended as a starting place. Use the output of this command and compare it to the release Google Sheet to identify commits that are ready to be released.

Pull in the appropriate commit(s) (sequentially).

git cherry-pick [sha]
# if more than one, repeat

Create a release request PR.

create_release_pr

Set a variable for the release pr number.

release_pr_number=[release-pr-number]

Wait for build to pass and then assign reviewers.

Once approval has been received from all reviewers merge the PR using the "Create a merge commit" option. DO NOT SQUASH AND MERGE or REBASE AND MERGE!!!

Checkout master (and delete release branch).

git checkout master
git pull

Set a variable for the sha of the merge commit that was just created on master.

sha=[merge-commit-sha]

Tag the merge commit with a release version.

tag_release

Additinal Steps

On GitHub add the label "Shipped" to each PR that was just merged.

Update the release Google Sheet for each PR that was just shipped with the corresponding release request URL.

Send an update on the originating ZOHO ticket (where applicable) stating the deployment is complete and including a link to the release PR.

Refresh release Google Sheet

Periodically (or when requested) refresh the Google Sheet that tracks the history of what has been deployed to production by client.

Steps

Start up a terminal and switch to the appropriate config directory.

cd /path/to/config/incent-config-[client-key]

Capture a list of "un-shipped" features (PR's into config-changes not yet labeled Shipped).

capture_unshipped

Open un-shipped CSV file in default spreadsheet tool (Excel/Numbers etc.).

open prs-into-config-changes.csv

Copy rows that are not yet present in the release Google Sheet to the top (PR's in descending order).

#! /usr/bin/env bash
# query for PR's
# * repo - incent-config-[current-directory-name]
# * not labeled release
# * not labeled Shipped
# * base - config-changes
# * state is merged
unshipped() {
repo="technekes/${PWD##*/}"
gh api --paginate "search/issues?q=repo:$repo+base:config-changes+-label:release+-label:Shipped+is:merged" \
| jq --raw-output '["pull_request","program_set","description","deployed_to","ready_for_production"], (.items[] | [.html_url, (.title | split("]")), "staging"] | flatten) | @csv' \
| sed -e 's/\[//g'
}
view_unshipped() {
unshipped \
| csvlook --blanks --no-inference
}
capture_unshipped() {
unshipped \
> prs-into-config-changes.csv
}
create_issue() {
if [ -z "$program_set" ] || [ -z "$ticket" ] ; then
echo "program_set or ticket not set"
else
gh issue create \
--title "[$program_set] Deployment Request" \
--project "Incent" \
--label "size: 1" \
--label "priority: 1 - urgent" \
--body="Deploy the latest version of $program_set to production.
ZOHO-$ticket
"
fi
}
diff_program_set() {
if [ -z "$program_set" ] ; then
echo "program_set not set"
else
git log \
--pretty=format:'%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' \
--abbrev-commit \
--date=relative \
..config-changes \
| grep "$program_set" \
| tac
fi
}
create_release_branch() {
if [ -z "$program_set" ] ; then
echo "program_set not set"
else
branch="release/$program_set/$(date "+%Y-%m-%d")/01"
echo "$branch"
git checkout config-changes \
&& git pull \
&& git checkout master \
&& git pull \
&& git checkout -b "$branch"
diff_program_set "$program_set"
fi
}
create_release_pr() {
if [ -z "$program_set" ] || [ -z "$issue" ] || [ -z "$ticket" ] ; then
echo "program_set or issue or ticket not set"
else
day=$(date +%e)
case $day in
1?) day=${day}th ;;
*1) day=${day}st ;;
*2) day=${day}nd ;;
*3) day=${day}rd ;;
*) day=${day}th ;;
esac
date=$(date "+%B $day %Y")
assignee=$(cat ~/.config/gh/hosts.yml | grep user | awk '{print $2}')
gh pr create \
--assignee $assignee \
--base master \
--label release \
--project Incent \
--title "[$program_set] Production Deployment" \
--body "$date Production Deployment
Resolves #$issue
ZOHO-$ticket
"
fi
}
tag_release() {
if [ -z "$program_set" ] || [ -z "$release_pr_number" ] || [ -z "$sha" ] ; then
echo "program_set or release_pr_number or sha not set"
else
today=$(date "+%Y-%m-%d")
annotation="$program_set/$today/$release_pr_number"
message="[$program_set] $today - Release PR #$release_pr_number"
git tag \
--annotate "$annotation" \
--message "$message" \
"$sha"
git push --tags
fi
}
label_shipped_prs() {
if [ -z "$1" ] ; then
echo "PR number(s) required"
else
for pr_number in "$@"; do
gh pr edit $pr_number --add-label "shipped"
done
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment