From 6b039b71abc6c7a5e4c5595187053799b69ee63b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 20 Mar 2025 13:17:11 -0400 Subject: [PATCH] Add a post-deploy hook to tag the release and post to basecamp These scripts were only slightly modified from the versions in bc3 --- .kamal/hooks/docker-setup.sample | 3 - .kamal/hooks/post-deploy | 15 ++++ .kamal/hooks/post-deploy.sample | 14 ---- .kamal/hooks/post-proxy-reboot.sample | 3 - .kamal/hooks/pre-build.sample | 51 ------------ .kamal/hooks/pre-connect.sample | 47 ----------- .kamal/hooks/pre-deploy.sample | 109 -------------------------- .kamal/hooks/pre-proxy-reboot.sample | 3 - bin/broadcast_to_bc | 3 + 9 files changed, 18 insertions(+), 230 deletions(-) delete mode 100755 .kamal/hooks/docker-setup.sample create mode 100755 .kamal/hooks/post-deploy delete mode 100755 .kamal/hooks/post-deploy.sample delete mode 100755 .kamal/hooks/post-proxy-reboot.sample delete mode 100755 .kamal/hooks/pre-build.sample delete mode 100755 .kamal/hooks/pre-connect.sample delete mode 100755 .kamal/hooks/pre-deploy.sample delete mode 100755 .kamal/hooks/pre-proxy-reboot.sample create mode 100755 bin/broadcast_to_bc diff --git a/.kamal/hooks/docker-setup.sample b/.kamal/hooks/docker-setup.sample deleted file mode 100755 index 2fb07d7d7..000000000 --- a/.kamal/hooks/docker-setup.sample +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -echo "Docker set up on $KAMAL_HOSTS..." diff --git a/.kamal/hooks/post-deploy b/.kamal/hooks/post-deploy new file mode 100755 index 000000000..9ad72e66a --- /dev/null +++ b/.kamal/hooks/post-deploy @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +MESSAGE="$KAMAL_PERFORMER deployed $KAMAL_SERVICE_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + +if [[ $CURRENT_BRANCH == "main" && $KAMAL_DESTINATION == "production" ]]; then + gh release create $KAMAL_SERVICE_VERSION --target $KAMAL_VERSION --generate-notes 2> /dev/null || true + + RELEASE_URL=$(gh release view $KAMAL_SERVICE_VERSION --json url,body --jq .url) + RELEASE_BODY=$(gh release view $KAMAL_SERVICE_VERSION --json url,body --jq .body) + + bin/broadcast_to_bc "$MESSAGE "$'\n'"$RELEASE_URL "$'\n'"$RELEASE_BODY" +else + bin/broadcast_to_bc "$MESSAGE" +fi diff --git a/.kamal/hooks/post-deploy.sample b/.kamal/hooks/post-deploy.sample deleted file mode 100755 index 75efafc10..000000000 --- a/.kamal/hooks/post-deploy.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -# A sample post-deploy hook -# -# These environment variables are available: -# KAMAL_RECORDED_AT -# KAMAL_PERFORMER -# KAMAL_VERSION -# KAMAL_HOSTS -# KAMAL_ROLE (if set) -# KAMAL_DESTINATION (if set) -# KAMAL_RUNTIME - -echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" diff --git a/.kamal/hooks/post-proxy-reboot.sample b/.kamal/hooks/post-proxy-reboot.sample deleted file mode 100755 index 1435a677f..000000000 --- a/.kamal/hooks/post-proxy-reboot.sample +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -echo "Rebooted kamal-proxy on $KAMAL_HOSTS" diff --git a/.kamal/hooks/pre-build.sample b/.kamal/hooks/pre-build.sample deleted file mode 100755 index f87d81130..000000000 --- a/.kamal/hooks/pre-build.sample +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -# A sample pre-build hook -# -# Checks: -# 1. We have a clean checkout -# 2. A remote is configured -# 3. The branch has been pushed to the remote -# 4. The version we are deploying matches the remote -# -# These environment variables are available: -# KAMAL_RECORDED_AT -# KAMAL_PERFORMER -# KAMAL_VERSION -# KAMAL_HOSTS -# KAMAL_ROLE (if set) -# KAMAL_DESTINATION (if set) - -if [ -n "$(git status --porcelain)" ]; then - echo "Git checkout is not clean, aborting..." >&2 - git status --porcelain >&2 - exit 1 -fi - -first_remote=$(git remote) - -if [ -z "$first_remote" ]; then - echo "No git remote set, aborting..." >&2 - exit 1 -fi - -current_branch=$(git branch --show-current) - -if [ -z "$current_branch" ]; then - echo "Not on a git branch, aborting..." >&2 - exit 1 -fi - -remote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1) - -if [ -z "$remote_head" ]; then - echo "Branch not pushed to remote, aborting..." >&2 - exit 1 -fi - -if [ "$KAMAL_VERSION" != "$remote_head" ]; then - echo "Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting..." >&2 - exit 1 -fi - -exit 0 diff --git a/.kamal/hooks/pre-connect.sample b/.kamal/hooks/pre-connect.sample deleted file mode 100755 index 18e61d7e5..000000000 --- a/.kamal/hooks/pre-connect.sample +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env ruby - -# A sample pre-connect check -# -# Warms DNS before connecting to hosts in parallel -# -# These environment variables are available: -# KAMAL_RECORDED_AT -# KAMAL_PERFORMER -# KAMAL_VERSION -# KAMAL_HOSTS -# KAMAL_ROLE (if set) -# KAMAL_DESTINATION (if set) -# KAMAL_RUNTIME - -hosts = ENV["KAMAL_HOSTS"].split(",") -results = nil -max = 3 - -elapsed = Benchmark.realtime do - results = hosts.map do |host| - Thread.new do - tries = 1 - - begin - Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) - rescue SocketError - if tries < max - puts "Retrying DNS warmup: #{host}" - tries += 1 - sleep rand - retry - else - puts "DNS warmup failed: #{host}" - host - end - end - - tries - end - end.map(&:value) -end - -retries = results.sum - hosts.size -nopes = results.count { |r| r == max } - -puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ] diff --git a/.kamal/hooks/pre-deploy.sample b/.kamal/hooks/pre-deploy.sample deleted file mode 100755 index 1b280c719..000000000 --- a/.kamal/hooks/pre-deploy.sample +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env ruby - -# A sample pre-deploy hook -# -# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds. -# -# Fails unless the combined status is "success" -# -# These environment variables are available: -# KAMAL_RECORDED_AT -# KAMAL_PERFORMER -# KAMAL_VERSION -# KAMAL_HOSTS -# KAMAL_COMMAND -# KAMAL_SUBCOMMAND -# KAMAL_ROLE (if set) -# KAMAL_DESTINATION (if set) - -# Only check the build status for production deployments -if ENV["KAMAL_COMMAND"] == "rollback" || ENV["KAMAL_DESTINATION"] != "production" - exit 0 -end - -require "bundler/inline" - -# true = install gems so this is fast on repeat invocations -gemfile(true, quiet: true) do - source "https://rubygems.org" - - gem "octokit" - gem "faraday-retry" -end - -MAX_ATTEMPTS = 72 -ATTEMPTS_GAP = 10 - -def exit_with_error(message) - $stderr.puts message - exit 1 -end - -class GithubStatusChecks - attr_reader :remote_url, :git_sha, :github_client, :combined_status - - def initialize - @remote_url = `git config --get remote.origin.url`.strip.delete_prefix("https://github.com/") - @git_sha = `git rev-parse HEAD`.strip - @github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"]) - refresh! - end - - def refresh! - @combined_status = github_client.combined_status(remote_url, git_sha) - end - - def state - combined_status[:state] - end - - def first_status_url - first_status = combined_status[:statuses].find { |status| status[:state] == state } - first_status && first_status[:target_url] - end - - def complete_count - combined_status[:statuses].count { |status| status[:state] != "pending"} - end - - def total_count - combined_status[:statuses].count - end - - def current_status - if total_count > 0 - "Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ..." - else - "Build not started..." - end - end -end - - -$stdout.sync = true - -puts "Checking build status..." -attempts = 0 -checks = GithubStatusChecks.new - -begin - loop do - case checks.state - when "success" - puts "Checks passed, see #{checks.first_status_url}" - exit 0 - when "failure" - exit_with_error "Checks failed, see #{checks.first_status_url}" - when "pending" - attempts += 1 - end - - exit_with_error "Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds" if attempts == MAX_ATTEMPTS - - puts checks.current_status - sleep(ATTEMPTS_GAP) - checks.refresh! - end -rescue Octokit::NotFound - exit_with_error "Build status could not be found" -end diff --git a/.kamal/hooks/pre-proxy-reboot.sample b/.kamal/hooks/pre-proxy-reboot.sample deleted file mode 100755 index 061f8059e..000000000 --- a/.kamal/hooks/pre-proxy-reboot.sample +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." diff --git a/bin/broadcast_to_bc b/bin/broadcast_to_bc new file mode 100755 index 000000000..2fbd1e3e5 --- /dev/null +++ b/bin/broadcast_to_bc @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +curl -s -d content="[Fizzy] ${1}" https://3.basecamp.com/2914079/integrations/5c3a7bd149c975b95312253c/buckets/4896644/chats/676031034/lines