Skip to content

Instantly share code, notes, and snippets.

@dhh
Created April 29, 2024 18:39
Show Gist options
  • Save dhh/c5051aae633ff91bc4ce30528e4f0b60 to your computer and use it in GitHub Desktop.
Save dhh/c5051aae633ff91bc4ce30528e4f0b60 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Abort sign off on any error
set -e
# Start the benchmark timer
SECONDS=0
# Repository introspection
OWNER=$(gh repo view --json owner --jq .owner.login)
REPO=$(gh repo view --json name --jq .name)
SHA=$(git rev-parse HEAD)
USER=$(git config user.name)
# Progress reporting
GREEN=32; RED=31; BLUE=34
announce() { echo -e "\033[0;$2m$1\033[0m"; }
run() {
local SPLIT=$SECONDS
announce "\nRun $1" $BLUE
eval "$1"
local INTERVAL=$((SECONDS-SPLIT))
announce "Completed $1 in $INTERVAL seconds" $GREEN
}
# Sign off requires a clean repository
if [[ -n $(git status --porcelain) ]]; then
announce "Can't sign off on a dirty repository!" $RED
git status
exit 1
else
announce "Attempting to sign off on $SHA in $OWNER/$REPO as $USER" $GREEN
fi
# Required steps for sign off
run "./bin/rubocop"
run "./bin/bundle-audit check --update"
run "./bin/brakeman -q --no-summary"
run "./bin/rails test"
run "./bin/rails test:system"
# Report successful sign off to GitHub
gh api \
--method POST --silent \
-H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
/repos/$OWNER/$REPO/statuses/$SHA \
-f "context=signoff" -f "state=success" -f "description=Signed off by $USER ($SECONDS seconds)"
announce "Signed off on $SHA in $SECONDS seconds" $GREEN
@skyscooby
Copy link

Hopefully this script is being invoked inside a shared container runtime with managed dependencies so every developer is running the exact same tool versions.

It might also be reasonable from a security perspective to have your deploy branch running these tools on a machine that is isolated to prove reproducible deployment on a machine less likely to become compromised than a dev desktop. In a jam a developer might also just decide to # comment out any one of those run statements and you'd really have no central logs/output to review/audit. Maybe you could use the gh api to upload the output of the above jobs into the signoff somehow?

You can also do something similar with a git pre-commit hook.. https://github.com/pre-commit/pre-commit

@bersace
Copy link

bersace commented Apr 30, 2024

Is your CI slow because you reinstall earth every commit ? Having buildpack image and cache should help.

In ldap2pg, I end up running docker compose right in CircleCI machine executor. Docker executor don't have enough privileges to run Samba service. docker compose run test is a reproductible local or remote test environment. This is not a pipeline however. Some CI have local execution tooling. That may help.

@srid
Copy link

srid commented Apr 30, 2024

Hopefully this script is being invoked inside a shared container runtime with managed dependencies so every developer is running the exact same tool versions.

The other option is to use Nix. Then, nix build is reproducible across all machines of same architecture; you can even build docker images in Nix.

@dhh will find Nix to be the next red-pill, sooner or later. :-)
I personally run GitHub runners locally (setup through Nix) which happens to me on my laptop, but that doesn't obviously scale to N developer machines/

@skyscooby
Copy link

skyscooby commented Apr 30, 2024

is to use Nix

You must have missed his many other posts on complexity being a temporary bridge to simplicity.. Nix has only gotten more complex since it's inception.

The moment you need to either build your own packages or troubleshoot someone elses, you are faced with mountain of needless complexity. It certainly isn't a tool that should have required a unique turing complete language to achieve.

If everything works out as a user and you never have a Nix language issue, or a need to touch it, then it can work out ok.. but https://containers.dev is a more general solution for developers.

@crabmusket
Copy link

Does this hook into deployments, e.g. once a commit has a successful signoff status it can be automatically rolled into staging?

@gurgeous
Copy link

gurgeous commented May 1, 2024

Neat, thanks for sharing. Might also consider moving some things into a justfile - we are using that tool heavily across our projects now. Easy to add tasks for linting, formatting, tests, sanity checks, CI, deployment, foreman, builds, setup, whatever. Language agnostic, self documenting, handy for new hires, autocompletes in the shell, etc.

@albertodebortoli
Copy link

As a variation/alternative/improvement (!) to this, I considered using the devs' machines as runners. We need to assume that the workflows would install the required dependencies etc.

Very much valid what @skyscooby said about running on containers - in my scenario, bare-metal macOS instances are used (not virtualised) and availability can be scarce.

Here's a way to optionally use the devs' machine that when connected to GitHub Actions should have a label with the name of the branch.
If the dev machine is not connected as a dev-hosted runner, the workflow will try to run on self-hosted runners (shared instances), potentially sitting on the queue.

It could be an interesting option for some teams under certain conditions.

@crohr
Copy link

crohr commented May 17, 2024

@albertodebortoli or... one of the many drop-in replacements for official runners, but far cheaper? At least for jobs that can't be easily launched / take too long on a dev machine.

@albertodebortoli
Copy link

Hi @crohr, that is a valid point for Linux and Windows and therefore for most cases. For macOS though, there are not "many" alternatives and I would say that compared to Linux runners, there's nothing "cheap".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment