Skip to content

Contributing

Bob Vawter edited this page Jun 13, 2024 · 16 revisions

Contributing

Actions

Binaries

The Binaries workflow runs go build at the top of the repository and uploads it to a GCP storage bucket. Links to this storage bucket are in Installing.

The GCP bucket access key is stored in the GitHub repository secret CDC_SINK_BINARIES_KEY. If the JSON key is regenerated, be sure to minimize the json before adding it to the secret: cat path/to/replicator-b94d221f7ddf.json | jq -r tostring | pbcopy. If you don't minimize the key, the build log output will be mangled by the secrets-masking behavior, since that operates on a per-secret-line basis.

Docker

The Docker workflow uploads linux/amd64 and linux/arm64 images to DockerHub using the CRL-organization account.

Firestore Emulator

The Firestore emulator workflow builds a local copy of the Google Firestore Emulator for use by integration tests.

Golang

The Golang workflow runs code-quality and go test.

Markdown

The Markdown workflow runs a basic linter for any changes to *.md files.

Wiki

The Wiki workflow updates wiki pages when replicator CLI flags change. It runs a tool that looks for comments like:

<!-- marksub: start.help.txt -->

and replaces the immediately following code block with the contents of the named file. These help.txt files are created by a hidden replicator dumphelp command.

PR workflow

The automated test workflows depend upon having a repository secret containing a CockroachDB enterprise license key, so it's necessary for authors to create their PRs on the Replicator repository itself. At present, there's no way to allow this secret to be borrowed by PR's created in forks.

The Replicator repository uses the GitHub merge queue, where the master branch protection rule references the [meta-workflow status](#Workflow Status Bypass) objects. It currently requires that the Golang and Binaries workflows complete successfully.

Commit messages should be comprehensive; follow the CockroachDB Git Commit Messages guidelines.

Workflow Status Bypass

Should it be necessary to manually create a meta-workflow status because (e.g. a PR doesn't make changes to trigger the workflow), execute the following:

# The {owner}/{repo} are substituted by the gh command itself.
# You'll need to update the SHA and name of the Workflow.
gh api repos/{owner}/{repo}/statuses/<<SHA>> -f state=success -f context='Workflow <<XYZZY>>'

Breaking changes

If a breaking change needs to be made (e.g. to tables in the _replicator schema), it's necessary to add a new entry to version/versions.go. This will prevent a new build of Replicator from starting until the necessary entry has been added to the memo table as shown below. The PR commit message should include the necessary SQL or other process to perform the migration. This information should also be repeated in a file migrations/pr_1234.md so that the instructions can be revised at a later point.

INSERT INTO memo VALUES ('version-1234', '{"state":"applied"}');

Recipes

Refresh generated code

go generate ./...

Pre-commit commands

These are checked by the code-quality build step. You'll want to run them before creating a PR.

# Ensure copyright in new files
go run github.com/google/addlicense -c "The Cockroach Authors" -l apache -s -v .

# Standardize formatting
go run github.com/cockroachdb/crlfmt -ignore _gen.go .

# Lints
go run golang.org/x/lint/golint -set_exit_status ./...
go run honnef.co/go/tools/cmd/staticcheck -checks all ./...

Testing target databases

The test rig uses the environment variable TEST_TARGET_CONNECT to override the test database.

The source for this table is go-test.yaml.

Product Environment
CRDB None needed
MySQL TEST_TARGET_CONNECT=mysql://root:SoupOrSecret@localhost:3306/
Oracle TEST_TARGET_CONNECT=oracle://system:[email protected]:1521/XEPDB1
PostgreSQL TEST_TARGET_CONNECT=postgres://postgres:[email protected]:5432

Wire

Replicator makes use of Wire for compile-time dependency injection. Wire, unlike some other DI implementations, only manages singleton instances and is pretty much free of any "magic". Wire is useful for Replicator because we have several different modes of operation that don't need all services all of the time. It also eliminates the need to manually plumb new service instances all the way through the code-base.