From 7933abf926f06fddb6d33051fd4db6a04ca5d1b2 Mon Sep 17 00:00:00 2001 From: vados Date: Sun, 29 Oct 2023 12:14:25 +0900 Subject: [PATCH] chore(workflow): convert Makefile to Justfile Just (https://github.com/casey/just) is a command runner similar to Make that's much more concise and has more features. This commit replaces the project Makefile with a Justfile, and updates documentation to alert people to this change. Signed-off-by: vados --- Justfile | 111 ++++++++++++++++++++++++++++++++++++++++++ Makefile | 129 ------------------------------------------------- README.md | 141 +++++++++++++++++++++++++++++------------------------- 3 files changed, 188 insertions(+), 193 deletions(-) create mode 100644 Justfile delete mode 100644 Makefile diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..322f3b4 --- /dev/null +++ b/Justfile @@ -0,0 +1,111 @@ +cargo := env_var_or_default("CARGO", "cargo") +cargo_get := env_var_or_default("CARGO_GET", "cargo-get") +cargo_watch := env_var_or_default("CARGO_WATCH", "cargo-watch") +docker := env_var_or_default("DOCKER", "docker") +git := env_var_or_default("GIT", "git") +just := env_var_or_default("JUST", just_executable()) + +changelog_path := "CHANGELOG" + +default: + {{just}} --list + +########### +# Tooling # +########### + +_check-installed-version tool msg: + #!/usr/bin/env -S bash -euo pipefail + if [ -z "$(command -v {{tool}})" ]; then + echo "{{msg}}"; + exit 1; + fi + +@_check-tool-cargo: + {{just}} _check-installed-version {{cargo}} "'cargo' not available, please install the Rust toolchain (see: https://github.com/rust-lang/cargo/)"; + +@_check-tool-cargo-watch: + {{just}} _check-installed-version {{cargo_watch}} "'cargo-watch' not available, please install cargo-watch (https://github.com/passcod/cargo-watch)" + +@_check-tool-cargo-get: + {{just}} _check-installed-version {{cargo_get}} "'cargo-get' not available, please install cargo-get (https://crates.io/crates/cargo-get)" + +######### +# Build # +######### + +version := `grep 'version' Cargo.toml | head -n 1 | sed -rn 's/version\s*=\s*(.*)/\1/p'` + +# NOTE: we can't use this as the official version getter until +# see: https://github.com/nicolaiunrein/cargo-get/issues/14 +@get-version: _check-tool-cargo-get + cargo get package.version + +print-version: + #!/usr/bin/env -S bash -euo pipefail + echo -n `{{just}} get-version` + +changelog: + {{git}} cliff --unreleased --tag=$(VERSION) --prepend=$(CHANGELOG_FILE_PATH) + +build: + {{cargo}} build + +build-watch: _check-tool-cargo _check-tool-cargo-watch + {{cargo_watch}} -x "build $(CARGO_BUILD_FLAGS)" --watch src + +build-test-watch: _check-tool-cargo _check-tool-cargo-watch + {{cargo_watch}} -x "test $(CARGO_BUILD_FLAGS)" --watch src + +package: + {{cargo}} pgrx package + +test: + {{cargo}} test + {{cargo}} pgrx test + +########## +# Docker # +########## + +pg_image_version := env_var_or_default("POSTGRES_IMAGE_VERSION", "15.1.0") +pg_image_tag := env_var_or_default("POSGRES_IMAGE_VERSION", pg_image_version + "-alpine") + +pgkit_image_name := env_var_or_default("PGKIT_IMAGE_NAME", "postgres") +pgkit_image_tag := env_var_or_default("PGKIT_IMAGE_TAG", pg_image_version + "-pg_idkit=" + version) +pgkit_image_name_full := env_var_or_default("PGKIT_IMAGE_NAME_FULL", pgkit_image_name + ":" + pgkit_image_tag) +pgkit_dockerfile_path := env_var_or_default("PGKIT_DOCKERFILE_PATH", "infra" / "docker" / pgkit_image_tag + ".Dockerfile") + +ci_dockerfile_path := env_var_or_default("CI_DOCKERFILE_PATH", "infra" / "docker" / "ci.Dockerfile") +ci_image_name := env_var_or_default("CI_IMAGE_NAME", "ghcr.io/vadosware/pg_idkit/builder") +ci_image_tag := env_var_or_default("CI_IMAGE_TAG", "0.x.x") +ci_image_name_full := env_var_or_default("CI_IMAGE_NAME_FULL", ci_image_name + ":" + ci_image_tag) + +docker_password_path := env_var_or_default("DOCKER_PASSWORD_PATH", "secrets/docker/password.secret") +docker_username_path := env_var_or_default("DOCKER_USERNAME_PATH", "secrets/docker/username.secret") +docker_image_registry := env_var_or_default("DOCKER_IMAGE_REGISTRY", "ghcr.io/vadosware/pg_idkit") +docker_config_dir := env_var_or_default("DOCKER_CONFIG", "secrets/docker") + +## Ensure that that a given file is present +_ensure-file file: + #!/usr/bin/env -S bash -euo pipefail + @if [ ! -f "{{file}}" ]; then + echo "[error] file [{{file}}] is required, but missing"; + exit 1; + fi; + +# Log in with docker using local credentials +docker-login: + {{just}} ensure-file {{docker_password_path}} + {{just}} ensure-file {{docker_username_path}} + cat {{docker_password_path}} | {{docker}} login {{docker_image_registry}} -u `cat {{docker_username_path}}` --password-stdin + cp {{docker_config_dir}}/config.json {{docker_config_dir}}/.dockerconfigjson + +image: + {{docker}} build -f {{pgkit_dockerfile_path}} -t {{pgkit_image_name_full}} + +build-ci-image: + {{docker}} build -f {{ci_dockerfile_path}} -t {{ci_image_name_full}} . + +push-ci-image: + {{docker}} push {{ci_image_name_full}} diff --git a/Makefile b/Makefile deleted file mode 100644 index b059360..0000000 --- a/Makefile +++ /dev/null @@ -1,129 +0,0 @@ -# Makefile preamble (https://tech.davis-hansson.com/p/make/) -SHELL := bash -.ONESHELL: -.SHELLFLAGS := -eu -o pipefail -c -.DELETE_ON_ERROR: -MAKEFLAGS += --warn-undefined-variables -MAKEFLAGS += --no-builtin-rules -MAKEFLAGS += --no-print-directory -MAKEFLAGS += --quiet - -ifeq ($(origin .RECIPEPREFIX), undefined) - $(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later) -endif -.RECIPEPREFIX = > - -OPENSSL ?= openssl -DOCKER ?= docker - -PULUMI_SECRET_DIR ?= secrets/pulumi -PULUMI_AWS_ACCESS_KEY_ID_PATH ?= $(PULUMI_SECRET_DIR)/aws-access-key-id.secret -PULUMI_AWS_SECRET_ACCESS_KEY_PATH ?= $(PULUMI_SECRET_DIR)/aws-secret-access-key.secret - -.PHONY: all \ -# Tooling -> check-tool-cargo check-tool-cargo-watch \ -# Build -> print-version \ -> build build-watch build-test-watch \ -> package test \ -# Docker -> image \ -> build-ci-image push-ci-image \ -> docker-login ensure-file - -CARGO ?= cargo -CARGO_WATCH ?= cargo-watch - -CHANGELOG_FILE_PATH ?= CHANGELOG - -all: build - -########### -# Tooling # -########### - -check-tool-cargo: -ifeq (,$(shell which $(CARGO))) -> $(error "please enture cargo and the rust toolchain is installed (see: https://github.com/rust-lang/cargo/)") -endif - -check-tool-cargo-watch: -ifeq (, $(shell which $(CARGO_WATCH))) -> $(error "`cargo-watch` is not available please install cargo-watch (https://github.com/passcod/cargo-watch)") -endif - -######### -# Build # -######### - -# NOTE: this assumes the *first* version is the package version -VERSION ?= $(shell grep 'version' Cargo.toml | head -n 1 | sed -rn 's/version\s*=\s*(.*)/\1/p') - -print-version: -> @echo -n "$(VERSION)" - -changelog: -> $(GIT) cliff --unreleased --tag=$(VERSION) --prepend=$(CHANGELOG_FILE_PATH) - -build: -> $(CARGO) build - -build-watch: check-tool-cargo check-tool-cargo-watch -> $(CARGO_WATCH) -x "build $(CARGO_BUILD_FLAGS)" --watch src - -build-test-watch: check-tool-cargo check-tool-cargo-watch -> $(CARGO_WATCH) -x "test $(CARGO_BUILD_FLAGS)" --watch src - -package: -> $(CARGO) pgrx package - -test: -> $(CARGO) test -> $(CARGO) pgrx test - -########## -# Docker # -########## - -POSTGRES_IMAGE_VERSION ?= 15.1.0 -POSTGRES_IMAGE_TAG ?= ${POSTGRES_IMAGE_VERSION}-alpine - -IMAGE_NAME ?= postgres -IMAGE_TAG ?= ${POSTGRES_IMAGE_VERSION}-pg_idkit-${VERSION} -IMAGE_NAME_FULL ?= "$(IMAGE_NAME):$(IMAGE_TAG)" - -DOCKERFILE_PATH ?= ./infra/docker/${POSTGRES_IMAGE_TAG}.Dockerfile - -CI_DOCKERFILE_PATH ?= ./infra/docker/ci.Dockerfile -CI_IMAGE_NAME ?= ghcr.io/vadosware/pg_idkit/builder -CI_IMAGE_TAG ?= 0.x.x -CI_IMAGE_NAME_FULL ?= "$(CI_IMAGE_NAME):$(CI_IMAGE_TAG)" - -DOCKER_PASSWORD_PATH ?= secrets/docker/password.secret -DOCKER_USERNAME_PATH ?= secrets/docker/username.secret -DOCKER_IMAGE_REGISTRY ?= ghcr.io/vadosware/pg_idkit -DOCKER_CONFIG ?= secrets/docker - -## Ensure that that a given file is present -ensure-file: -> @if [ ! -f "$(FILE)" ]; then \ - echo "[error] file [$(FILE)] is required, but missing"; \ - exit 1; \ - fi; - -# Log in with docker using local credentials -docker-login: -> $(MAKE) ensure-file FILE=$(DOCKER_PASSWORD_PATH) -> $(MAKE) ensure-file FILE=$(DOCKER_USERNAME_PATH) -> cat $(DOCKER_PASSWORD_PATH) | $(DOCKER) login $(DOCKER_IMAGE_REGISTRY) -u `cat $(DOCKER_USERNAME_PATH)` --password-stdin -> cp $(DOCKER_CONFIG)/config.json $(DOCKER_CONFIG)/.dockerconfigjson - -image: -> $(DOCKER) build -f $(DOCKERFILE_PATH) -t $(IMAGE_NAME_FULL) - -build-ci-image: -> $(DOCKER) build -f $(CI_DOCKERFILE_PATH) -t $(CI_IMAGE_NAME_FULL) . - -push-ci-image: -> $(DOCKER) push $(CI_IMAGE_NAME_FULL) diff --git a/README.md b/README.md index fa202de..0f9a973 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,9 @@ Here are some you may or may not have heard of: - [`geckoboard/pgulid`](https://github.com/geckoboard/pgulid) - [this gist by `fabiolimace` for generating UUIDv6](https://gist.github.com/fabiolimace/515a0440e3e40efeb234e12644a6a346) -# Installing `pg_idkit` +## Installing `pg_idkit` -## Binary install +### Binary install If running a custom version of locally/globally manually installed Postgres, you may download (and verify the checksum of) a shared library version from the [releases](/releases), and add it as one of your `shared_preload_libraries` in `postgresql.conf`. @@ -42,7 +42,7 @@ Assuming you have downloaded the `pg_idkit-vX.X.X.so` file to `/etc/postgresql/e shared_preload_libraries = '/etc/postgresql/extensions/pg_idkit-vX.X.X.so' ``` -## Dockerfile +### Dockerfile To build `pg_idkit` into a Postgres instance you can use a `Dockerfile` like the following: @@ -50,54 +50,51 @@ To build `pg_idkit` into a Postgres instance you can use a `Dockerfile` like the TODO ``` -# Local Development +## Local Development Here's how to get started working on `pg_idkit` locally. -## Prerequisites +### Prerequisites To work on `pg_idkit`, you'll need the following: -- [Rust][rust] toolchain ([`rustup`][rustup]) -- [`pgrx`][pgrx] and it's toolchain (the rust subcommand) +- [Rust][rust] toolchain (via [`rustup`][rustup]) +- [`cargo-pgrx`][cargo-pgrx] (see below for more details) +- [`just`][just] (see below for more details) - (optional) [`git-crypt`][git-crypt] (for working with secrets) - (optional) [direnv][direnv] - (optional) [Docker][docker] - (optional) [`cargo-watch`][cargo-watch] -[direnv]: https://direnv.net -[git-crypt]: https://github.com/AGWA/git-crypt - -## Setting up the local environment +#### `just` -Assuming you are using something like [`direnv`][direnv], use the following `.envrc` file: +This project uses a task runner similar to `make` called [`just`][just]. You can install it easily with `cargo`: +```console +cargo install --locked just ``` -# Use local docker auth file -export DOCKER_CONFIG=$(realpath secrets/docker) -``` - -**NOTE**, that is *not* a `.env` file, it is a `.envrc` file, with separate semantics -[direnv]: https://direnv.net +#### `cargo-pgrx` -## Install `cargo-pgrx` +Installing ```console -cargo install cargo-pgrx@0.9.7 +cargo install --locked cargo-pgrx cargo pgrx init ``` ## Building the project +To build the project: + ```console -make build +just build ``` To run the build continuously for quicker local development (assuming you have `cargo-watch` installed): ```console -make build-watch +just build-watch ``` ### `pgrx` workflow @@ -105,7 +102,7 @@ make build-watch Note that you can use the `pgrx`-documented development flow as well (using `cargo pgrx`) as well, for example: ```console -cargo pgrx run pg14 +cargo pgrx run pg15 ``` ## Run tests @@ -113,13 +110,13 @@ cargo pgrx run pg14 To run the tests: ```console -make test +just test ``` To run tests continuously for quicker local development (requires `cargo-watch`): ```console -make build-test-watch +just build-test-watch ``` ## Starting a local Postgres instance with `pg_idkit` installed @@ -127,22 +124,22 @@ make build-test-watch Assuming you have Docker installed, to start a local Postgres instance first you must build a `postgres` docker image with `pg_idkit`: ```console -make image +just image ``` Then start the container: ```console -make db-local +just db-local ``` You may attach to the local DB with `psql` and execute commands: ```console -make db-local-psql +just db-local-psql ``` -## Continuous Integration +# Continuous Integration To push up images that are used from continuous integration: @@ -150,49 +147,65 @@ To push up images that are used from continuous integration: 2. Ensuring `DOCKER_LOGIN` is set (see instructions above) 3. Perform a login 1. Manually via `echo $GH_PAT | docker login ghcr.io -u --password-stdin` - 2. Automatically, via `make docker-login` which will use the `git-crypt` protected credentials (you must have run `git-crypt` unlock first) + 2. Automatically, via `just docker-login` which will use the `git-crypt` protected credentials (you must have run `git-crypt` unlock first) 4. Observe the docker login credentials generated in this local repo directory (`secrets/docker/config.json`) -5. Run `make build-ci-image push-ci-image` +5. Run `just build-ci-image push-ci-image` -[pgrx]: https://github.com/tcdi/pgrx -[github-ai]: https://github.com/ai -[rfc-4122-update]: https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04 +# Packaging + +## Setting up for Docker usage + +Assuming you are using something like [`direnv`][direnv], use the following `.envrc` file: + +``` +# Use local docker auth file +export DOCKER_CONFIG=$(realpath secrets/docker) +``` + +**NOTE**, that is *not* a `.env` file, it is a `.envrc` file, with separate semantics + +[a-chilton]: https://github.com/chilts +[a-feerasta]: https://github.com/alizain +[cargo-pgrx]: https://crates.io/crates/cargo-pgrx [cargo-watch]: https://github.com/passcod/cargo-watch -[uuidv1]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address) -[ksuid]: https://github.com/segmentio/ksuid -[ulid]: https://github.com/ulid/spec -[pushid]: https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html -[cuid]: https://github.com/paralleldrive/cuid [cuid2]: https://github.com/paralleldrive/cuid2 -[xid]: https://github.com/rs/xid -[objectid]: https://www.mongodb.com/docs/manual/reference/method/ObjectId/ -[nanoid]: https://www.npmjs.com/package/nanoid -[wiki-uuid]: https://en.wikipedia.org/wiki/Universally_unique_identifier -[twitter]: https://blog.twitter.com/engineering -[wiki-mac-address]: https://en.wikipedia.org/wiki/MAC_address +[cuid]: https://github.com/paralleldrive/cuid +[direnv]: https://direnv.net +[direnv]: https://direnv.net +[docker]: https://docs.docker.com/get-started/overview/ +[e-elliott]: https://github.com/ericelliott +[git-crypt]: https://github.com/AGWA/git-crypt +[github-ai]: https://github.com/ai +[google]: https://google.com [instagram]: instagram-engineering.com/ -[p-pearcy]: https://github.com/ppearcy/elasticflake -[segment]: https://segment.com/blog/engineering/ -[r-tallent]: https://github.com/richardtallent -[a-chilton]: https://github.com/chilts [it-cabrera]: https://darkghosthunter.medium.com/ -[sony]: https://github.com/sony -[t-pawlak]: https://github.com/T-PWK -[a-feerasta]: https://github.com/alizain -[google]: https://google.com -[o-poitrey]: https://github.com/rs +[ksuid]: https://github.com/segmentio/ksuid [mongodb]: https://www.mongodb.com/blog/channel/engineering-blog -[e-elliott]: https://github.com/ericelliott -[wiki-gregorian]: https://en.wikipedia.org/wiki/Gregorian_calendar -[rust]: https://rust-lang.org -[pg-docs-operator-classes]: https://www.postgresql.org/docs/current/indexes-opclass.html -[repo]: https://github.com/t3hmrman/pg_idkit +[nanoid]: https://www.npmjs.com/package/nanoid +[o-poitrey]: https://github.com/rs +[objectid]: https://www.mongodb.com/docs/manual/reference/method/ObjectId/ [oryx-pro]: https://system76.com/laptops/oryx +[p-pearcy]: https://github.com/ppearcy/elasticflake +[pg-docs-operator-classes]: https://www.postgresql.org/docs/current/indexes-opclass.html [pgstattuple]: https://www.postgresql.org/docs/current/pgstattuple.html -[uuidv6]: https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-01.html -[uuidv7]: https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-01.html -[twitter-snowflake]: https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake -[timeflake]: https://github.com/anthonynsimon/timeflake [postgres]: https://postgresql.org +[pushid]: https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html +[r-tallent]: https://github.com/richardtallent +[repo]: https://github.com/t3hmrman/pg_idkit +[rfc-4122-update]: https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04 +[rust]: https://rust-lang.org [rustup]: https://rust-lang.github.io/rustup -[docker]: https://docs.docker.com/get-started/overview/ +[segment]: https://segment.com/blog/engineering/ +[sony]: https://github.com/sony +[t-pawlak]: https://github.com/T-PWK +[timeflake]: https://github.com/anthonynsimon/timeflake +[twitter-snowflake]: https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake +[twitter]: https://blog.twitter.com/engineering +[ulid]: https://github.com/ulid/spec +[uuidv1]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address) +[uuidv6]: https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-01.html +[uuidv7]: https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-01.html +[wiki-gregorian]: https://en.wikipedia.org/wiki/Gregorian_calendar +[wiki-mac-address]: https://en.wikipedia.org/wiki/MAC_address +[wiki-uuid]: https://en.wikipedia.org/wiki/Universally_unique_identifier +[xid]: https://github.com/rs/xid