The datastore:// migration driver is now a self-contained golang-migrate
database.Driver that opens through github.com/hanzo-ds/go (the native
ClickHouse-wire driver registered as the database/sql name "datastore").
The ClickHouse-specific migration logic (multi-statement exec,
schema_migrations DDL, cluster/engine config, Version/SetVersion/Drop/Lock)
is ported directly into database/datastore, so it no longer embeds or
imports the upstream database/clickhouse driver or
github.com/ClickHouse/clickhouse-go.
- Delete database/clickhouse (driver + test + examples) and
internal/cli/build_clickhouse.go.
- internal/cli/build_datastore.go drops the clickhouse-go blank import.
- go.mod: drop github.com/ClickHouse/clickhouse-go, add
github.com/hanzo-ds/go v1.0.1; tidy. Zero clickhouse-go in go.mod,
go.sum, and the module/dependency graph.
- Port the driver test + example migrations under database/datastore
(integration test requires a live datastore/clickhouse-wire backend).
- Update README, release workflow build tags, bug report template.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Registers "datastore://" as a URL scheme that delegates to the
ClickHouse driver. This allows golang-migrate to natively connect
to Hanzo Datastore instances without URL rewriting in scripts.
* feat: remove dependency on "hashicorp/go-multierror"
It seems the project has been unmainted for quite some time already,
see for example https://github.com/hashicorp/go-multierror/issues/97
and https://github.com/hashicorp/go-multierror/issues/98.
This also removes an uneccessary dependency which slims down the go.mod.
Go as of version 1.20 supports appending errors by specifying
multiple "%w" formatters in the "fmt.Errorf"[^0] function.
[^0]: https://pkg.go.dev/fmt#Errorf
* feat: use errors.Join to combine multiple errors
As an update to the previous commit 59f084ea3be2e7ec9d912c1a311402b1e4c40df6,
use "errors.Join"[^0] instead of multiple "%w" formatters for "fmt.Errorf".
[^0]: https://pkg.go.dev/errors#Join
* chore: bring back unused util.go file as removing it is a breaking change
* Ensure bufferWriter is always closed and error is returned in Buffer()
* Ensure bufferWriter is always closed and error is returned in Buffer()
* addressed review comments. used named error and joined error to return final error
* Fixed defer block
---------
Co-authored-by: Chandra kant <chandra.kant@cohesity.com>
* Remove old versions of MongoDB
Removed:
| Release | Release Date | End of Life Date |
|-------------|---------------|------------------|
| MongoDB 3.4 | November 2016 | January 2020 |
| MongoDB 3.6 | November 2017 | April 2021 |
| MongoDB 4.0 | June 2018 | April 2022 |
| MongoDB 4.2 | August 2019 | April 2023 |
Added:
| Release | Release Date | End of Life Date |
|-------------|---------------|------------------|
| MongoDB 5.0 | July 2021 | October 2024 |
| MongoDB 6.0 | July 2022 | July 2025 |
| MongoDB 7.0 | August 2023 | August 2026 |
| MongoDB 8.0 | October 2024 | TBD |
https://www.mongodb.com/legal/support-policy/lifecycles
* test(postgres): run tests with PostgreSQL 17
Add PostgreSQL 17, remove PostgreSQL 12 (EOL since November 21, 2024).
https://www.postgresql.org/support/versioning/
* test(cockroachdb): remove old versions of CockroachDB in tests
Removed:
| Release | Released | Maintenance Support | Assistance Support | Latest |
|:-------------------:|:--------------------------------------:|:--------------------------------------------:|:--------------------------------------------:|:---------------------:|
| 2.1 | 6 years ago (30 Oct 2018) | Ended 5 years ago (30 Oct 2019) | Ended 4 years and 7 months ago (30 Apr 2020) | 2.1.11 (22 Jan 2020) |
| 2.0 | 6 years and 8 months ago (04 Apr 2018) | Ended 5 years and 8 months ago (04 Apr 2019) | Ended 5 years ago (04 Oct 2019) | 2.0.7 (28 Nov 2018) |
| 1.1 | 7 years ago (12 Oct 2017) | Ended 6 years ago (12 Oct 2018) | Ended 5 years and 8 months ago (12 Apr 2019) | 1.1.9 (01 Oct 2018) |
| 1.0 | 7 years ago (10 May 2017) | Ended 6 years ago (10 May 2018) | Ended 6 years ago (10 Nov 2018) | 1.0.7 (11 Feb 2018) |
Added:
| Release | Released | Maintenance Support | Assistance Support | Latest |
|:-------------------:|:--------------------------------------:|:--------------------------------------------:|:--------------------------------------------:|:---------------------:|
| 24.3 | 3 weeks ago (18 Nov 2024) | Ends in 11 months (18 Nov 2025) | Ends in 1 year and 5 months (18 May 2026) | 24.3.0 (20 Nov 2024) |
| 24.2 | 3 months and 4 weeks ago (12 Aug 2024) | Ends in 2 months (12 Feb 2025) | Ends in 2 months (12 Feb 2025) | 24.2.5 (11 Nov 2024) |
| 24.1 (Upcoming LTS) | 6 months and 3 weeks ago (20 May 2024) | Ends in 5 months (20 May 2025) | Ends in 11 months (20 Nov 2025) | 24.1.7 (11 Nov 2024) |
| 23.2 (Upcoming LTS) | 10 months ago (05 Feb 2024) | Ends in 1 month and 4 weeks (05 Feb 2025) | Ends in 7 months and 4 weeks (05 Aug 2025) | 23.2.16 (13 Nov 2024) |
* test(firebird): remove old versions of Firebird in tests
Removed: Firebird 2.5, see https://firebirdsql.org/en/discontinued-versions/
Added:
- Firebird 4.0 (https://firebirdsql.org/en/firebird-4-0-5/)
- Firebird 5.0 (https://firebirdsql.org/en/firebird-5-0-1/)
* test(clickhouse): run ClickHouse tests with official LTS image (24.8)
* Run go mod tidy
* Fix Github linting action
Changes:
* checkout before setting up go
* pin golangci-lint version
* Update supported db versions
* Use start-single-node instead of start for cockroachdb
When attempting to connect to a PostgreSQL database using certificate
credentials, authentication may fail due to permissions issues on the
certificate files. When using migrate in Kubernetes, this issue may be
unavoidable when using secrets.
The github.com/lib/pq library has resolved this issue as of v1.10.6, so
this commit updates that library to the latest release version (v1.10.9)
to resolve the issue in migrate.
* Add driver for pgx v5
Fixes#827
- Move existing driver into database/pgx/v4
- Make exported items into database/pgx into links to database/pgx/v4,
marked as Deprecated
- Remove most tests in database/pgx, leaving a couple of e2e tests
behind to help ensure backwards compatibility.
- Mark defunct ErrDatabaseDirty as Deprecated - no code returns it
- Bump pgx/v4 dependency
- Add test runs for newer Postgres versions
* Tweak pgx tags and registration strings
* Tweak registration strings
* fix issue of downloading and using github sourced migration files of 100MB >=1Mb (which previously failed to download due to their size and the api call performed) by preferring the go-github client library method 'DownloadContents' for such operations (which doesn't have the same limitation)
* empty commit & push to trigger ci
* Bump alpine images to version 3.16 and update golang image to one based on alpine 3.15
Signed-off-by: Thomas Spear <tspear@conquestcyber.com>
* Bump alpine image to version 3.16
Signed-off-by: Thomas Spear <tspear@conquestcyber.com>
* Bump go version to 1.18
Signed-off-by: Thomas Spear <tspear@conquestcyber.com>
* Revert "Bump go version to 1.18"
This reverts commit 7a7d2bfb0b4711012dbecc8e19b1a3c336ea7615.
* Revert "Bump alpine image to version 3.16"
This reverts commit b13c3b84dcb7abb4038d75389dff6dd509645f33.
* Upgrade docker image and migrate binary to golang 1.19, and use build stages in docker image
Signed-off-by: Thomas Spear <tspear@conquestcyber.com>
* Back out unnecessary changes
Signed-off-by: Thomas Spear <tspear@conquestcyber.com>
Co-authored-by: Dale Hui <dhui@users.noreply.github.com>
The example:
`clickhouse://username:password@host:port/database=clicks?x-multi-statement=true`
did not work, but:
`clickhouse://host:port?username=user&password=password&database=clicks&x-multi-statement=true`
does.
I got the above DSN format from the tests.
As of Go 1.16, the same functionality is now provided by package io or
package os, and those implementations should be preferred in new code.
So replacing all usage of ioutil pkg with io & os.
Exposes the cassandra client's ConnectTimeout parameter through
the cassandra database query string.
The Cassandra client has a fairly aggressive connect timeout of
600ms, which can cause flakiness in certain network environments
or in Cassandra-compatible clusters with a more complex process
for establishing connections (i.e. ScyllaDB).
The query timeout is already configurable and exposed, but does
not impact the connect timeout in the gocql driver. This change
allows for configurtion of both.
The current example for the Clickhouse DSN is incorrect and will result in the client trying to use the default username, database, and password regardless of what is set in the DSN. This change fixed the DNS example to be correct for the current versions of the clickhouse-go client.
* Resolves#647 - Fixes typos in Mongo advisory locking parameters
* PR Feedback for #647 - Error out when both params set
* Fixes lint issues with #647
* Additional PR Fixes#647
* Lint fixes again #647
* One more tweak to CONTRIBUTING.md
* One more tweak to CONTRIBUTING.md, again
Co-authored-by: Steve Ramage <commits@sjrx.net>
Before this patch, clickhouse.WithInstance() would not select
DefaultMigrationsTableEngine when no MigrationsTableEngine was provided
through the clickhouse.Config{} argument. This behaviour forces the
caller to always provide explicitely the config's MigrationsTableEngine.
This patch make it so DefaultMigrationsTableEngine is used when
MigrationsTableEngine is not provided through clickhouse.Config{}.
Signed-off-by: Alexandre Perrin <alex@kaworu.ch>
* ci: migrate from CircleCI to GitHub Actions
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
* ci: merge release.yaml into ci.yaml
At the time of this commit, it is not possible to make the `goreleaser`
job run in a separate workflow and detect the tag push event, see [1].
[1]: https://stackoverflow.com/a/68078768/7902371
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
* goreleaser configuration and automatic release workflow
* update and fix goreleaser
* remove windows arm ignore
* add format override for windows to use zip files
* update environment and docker username
* the single source of truth
* fix depricated api issue ( thanks @dhui )
Co-authored-by: Mitsuo Heijo <mitsuo.heijo@gmail.com>
* Added a method to create a mysql database from a connection object
* Calling WithConnection from WithInstance to de-duplicate code
* Adding context and ping to mysql.WithConnection
* Interface type check at compile time
* MSI Auth for SQL Server
Add MSI Auth option to SQL Server connection. Default if no password is provided in connection string.
* Parse resource endpoint from server for msi
update host name parsing to get just the resource endpoint for msi
* Update go-mssqldb
update go-mssqldb to resolve panic issue referenced here: https://github.com/denisenkom/go-mssqldb/pull/642
* Update sqlserver.go
switch from deprecated methods. NewServicePrincipalTokenFromManagedIdentity calls the two methods that are deprecated for us
* Update sqlserver.go
add useMsi param instead of looking for nil password
* Update sqlserver readme
Update sqlserver readme for msi auth. make useMsi a bit safer
* Update sqlserver.go
remove comment
* Update database/sqlserver/README.md
Co-authored-by: Keegan Campbell <me@kfcampbell.com>
* Update sqlserver.go
refactor resource uri logic into its own method
* Update sqlserver_test.go
add tests for msi connection. can only test whether it fails with useMsi= true, or succeeds with useMsi=false
* Update sqlserver.go
check msi.EnsureFresh return value
* Return error for multiple auth and move query filter
move migrate.FilterCustomQuery(purl).String() into one line out of if/else. return error if both useMsi=true and password are passed
* Update README.md
update readme with warning for useMsi
* Update sqlserver_test.go
Update TestMsiFalse test case as now it should fail when useMsi=false and no password is provided
Co-authored-by: Keegan Campbell <me@kfcampbell.com>
* used uber atomic bool instead standard in lock/unlock db
* fixing local lock optimization implementation
* fixing mysql local lock optimization implementation
* fixing cockroachdb local lock optimization implementation
* CAS wrapper to automatically restore
* added test for cas with restore
* added atomic lock to sqlite & mongo
* added atomic lock to sqlite & mongo
* fix/refactor test cas restore function
* disable lock for mongo
* mongo local lock before acquiring the db lock
Co-authored-by: a.prinkov <aprinkov@ourgapps.com>
Changes:
- embedded variables must be at the package level
- re-use embedded FS in example for tests
- bump Go module version to 1.16 for tests to run
- This may cause issues building in 1.15
* clickhouse: make the table engine used for schema_migrations configurable
* clickhouse: tests creation with configurable table engine
* clickhouse: refactor tests to run with multiple table engines
* clickhouse: clarify the use case for the x-migrations-table-engine option
* clickhouse: fix naming consistency for the migrations table engine
* clickhouse: fix tests function wrap pattern
* Postgres and pgx - Add x-migrations-table-quoted url query option to postgres and pgx drivers (#95)
By default, gomigrate quote migrations table name, if `x-migrations-table-quoted` is enabled, then you must to quote migrations table name manually, for instance `"gomigrate"."schema_migrations"`
* Work In Progress
* Point docs link to `v4`
It's very confusing that when I land directly on `https://pkg.go.dev/github.com/golang-migrate/migrate` I get a the message:
> You are look at a deprecated version, use the latest version instead
But when I click the `latest version` link, it goes to a completely dead/wrong place.
So I think for almost anyone who actually wants to look at the real docs, it's a lot simpler to link straight to `v4` by default. If they want a different version, they can change that. But let's have the default point to a helpful place, and then you can go looking for the broken version, rather than the other way around.
* Update the badge link as well
* replace lib/pq dependency with pgx in postgres driver
* fix pgx error handling
pgconn is a low-level library, and errors from queries flow through higher-level pgx library
* update postgres tests to use pgx driver and error reporting
* update quoteIdentifier implementation to match lib/pq
* move changes for pgx support into new driver package
* add pgx driver to CLI
* restore examples used in testing for pgx driver
* replace postgres driver name with pgx in DSN in tests and docs
* consolidate connection string formatting in pgx testing
* lock pgx package at v4
Prior to v4, pgx did not support go modules. Version locking the import is the safest way to ensure we get the (as of now) latest version of the module. Additionally v4 implements some breaking changes to connection and error handling, which are also addressed in this commit.
* update parsed URL scheme instead of using string operation
* add pgx for builds using make
* add pgx to top level docs
* remove autogenerated TOC
* Add io/fs#FS Driver #471
* Refactor iofs.Iofs to be independent of httpfs
* Rename Iofs to IoFS, accepts fs.FS and use fs.DirEntry.Info() to undo the changes in ErrDuplicateMigration
* fix documents and migration directory for testing
* Fix iofs.Driver so that it can be used by embedding it like httpfs.PartialDriver
* iofs.Driver closes the file system if possible
* Rename receiver
* Refactor file driver to use iofs.Driver
* iofs build constraint is not needed so remove it
* Properly return an error in a corner case
* Increase golangci-lint timeout
* Fix example code
* Revert "Increase golangci-lint timeout"
This reverts commit 2cd12a63b50b7ac48d12dd0adc1ec4f4b49c3b93.
* unexport driver, add iofs.PartialDriver, remove type alias from file driver
* do not panic in Open, return error
* Add help statement for cli
Refers to #372
* Make constant for argument
* Create a flagset for each command
* Factor error handling
* Factor flagset creation
* fix: Typo and bad behaviour
* Fix lint error
* Fix according to the comments
* Fix according to the comments
* Force MigrationsTable on public schema
* Revert "Force MigrationsTable on public schema"
This reverts commit e5b25e8858ed42d19d420cb8bd16795c060994d2.
* Add example to fix search_path issue
* Use POSTGRESQL_URL in example and fix typo
* Make example simpler by using the `search_path` query parameter of the DB URL
* Added bitbucket cloud support as source for migration
* added test
* address PR Comments
* Add entry in README.md; update go.mod and go.sum
Co-authored-by: abhigupta91 <abhigupta0818@gmail.com>
Skipping `GET_LOCK`/`RELEASE_LOCK` is useful when running MySQL as
multi-master. This change simply disables the locking.
The internal client lock is left in place as a sanity check.
This is a copy of the existing sqlite3 driver, except that it imports `_
"github.com/mutecomm/go-sqlcipher/v4"` as database driver. This allows
to use migrate with encrypted sqlite databases.
* Include file path in errors from PartialDriver.ReadUp() and ReadDown()
* Use errors.Is(...) instead of os.Is...() in migrate.go: https://github.com/golang/go/issues/41122
- Update spanner library to cloud.google.com/go/spanner@v1.9.0
This prevents erroring on DDL statements like:
ALTER TABLE users ALTER COLUMN created
SET OPTIONS (allow_commit_timestamp = true);
https://github.com/googleapis/google-cloud-go/pull/2656
- Add test case which fails with older version of the library, and
succeeds with this one.
Fixes: #426
- include param in DSN example
- link to README docs on param (option) format
- switch to 'parameter' instead of 'option', in the main README, since
this is preferred
At the moment GCP Spanner backend does not seem to support comments
(issue being tracked at
https://issuetracker.google.com/issues/159730604).
By adding support for parsing the migration DDL with spansql we are
able to support comments and remove them before applying on the
database
* Bump spanner lib to v1.5.0
Will enable spanner emulator support
https://cloud.google.com/spanner/docs/emulator#go
Current version supports SPANNER_EMULATOR_HOST but fails at run-time
with spanner permission errors.
* go mod tidy
* Add pkger source driver support
As go-bindata has been abandoned [1] there are open requests, #116, for
alternative sources with similar functionality. The Buffalo project [2]
created packr and recently pkger [3] was announced [4] with the
intention to supersede packr.
This change adds support for using pkger as a source.
The implementation relies on httpfs.PartialDriver for pretty much all
functionality.
[1] https://github.com/jteeuwen/go-bindata/issues/5
[2] https://gobuffalo.io/
[3] https://github.com/markbates/pkger
[4] https://blog.gobuffalo.io/introducing-pkger-static-file-embedding-in-go-1ce76dc79c65
* pkger: rename Instance to Pkger
* pkger: make WithInstance accept *Pkger
* pkger: refactor and add access to global pkging.Pkger instance
* pkger: fix typo and cleanup debug logging
* Add neo4j driver on instance params
* Check constraint if exist return nil
* Create new driver if nil
* Remove URL and AuthToken from neo4j config
* Change call db constraint
* Add neo4j image 4.0
* Handle create new driver
* Use labels instead constraints
* Turn off TLS encryption on test
Move the migrate binary to `/usr/local/bin` in the Dockerfile, so
it can be invoked from anywhere - this makes it easier to write
entrypoint scripts which call `migrate` that can be used
consistently both locally and in Docker containers.
To preserve backwards compatibility for anything that depends on
`migrate` existing at its existing path, we create a symlink to the
`/usr/local/bin/migrate` binary.
* CLI: Improve migration creation.
* Validates migration version on creation, to avoid creation of duplicated versions
* Uses `os.OpenFile` with `O_CREATE|O_EXCL` to create files to avoid file collisions
* Uses `filepath.Join` to concatenate paths, making `cleanPath()` not necessary
* Prints generated filenames
* Fixes#238
* Supersedes #250
* CLI: change `createCmd` to return error and accept `print` parameter
* feat: print out an abs path
Better for Windows OS when specify -dir as /subdir, user will see C:/subdir/0001_name.up.sql rather than /subdir/0001_name.up.sql
* test: fixed abs path test fail for OS Windows
abs path tests fails because filepath.IsAbs() treats `/subdir` path as invalid abs path at windows when drive letter is not present
* feat: print absolute path for created files
Better for Windows OS systems where `/path` can be interpreted in different ways depending on working dir
* test: corrected tests for OS Windows
OS Windows has different interpretation of `/path`, it depends on working dir.
If working dir D:\test it interprets `/path` as `D:\path`
* test: fixed `dir invalid` test
Linux OS has less restriction on a filepath than Windows, so path invalid in windows is perfectly valid for Linux. The only invalid dir name in Linux is one ending with null string terminator (\000)
* refac(cli): *Cmd() now returns an error and not uses log.fatalErr(err)
* docs: added godoc, migarate usage updated
* refac(cli): code refactored
* refac: removed unnecessary path covert
* docs: comment added
* test: fixed code review issue, noErrorExpected var removed
https://github.com/golang-migrate/migrate/pull/352#discussion_r389409789
* docs: fixed godoc
Co-authored-by: Kiyoshi '13k' Murata <kbmurata@gmail.com>
An sqlite3 database may be opened with the x-no-tx-wrap=true query
parameter if the user would prefer to retain full control over the
bounds of their transactions. With x-no-tx-wrap enabled, migrations
should contain explicit BEGIN and COMMIT statements. This (optional)
behaviour for the sqlite3 driver is consistent with the default
behaviour for other drivers.
Fixes#346.
* initial pass
* new cli build file
* add ready function for docker start
* lowercase j
* explicit return
* test migration
* undo dockerfile change
* neo4j in dockerfile
* remove auth from url once transferred to auth token
* assorted review notes
* initial docs attempt
* unlock behavior more in line with lock behavior
* consistent naming
* linting
* seabolt in travis ci
* stdlib logger
* install seabolt as sudo
* enabled cgo
* correct version #
* remove neo4j todo
* named return values for errors
* review notes
* add libssl for alpine
* updates for review
* updates for neo driver
* go mod tidy
* adding/removing a new field in the schema
* example of updating field value from other fields
* added new line at end of files
Co-authored-by: Dale Hui <dhui@users.noreply.github.com>
This PR adds a new httpfs source driver constructor New(). It is
identical to the WithInstance() constructor but will postpone any errors
until the driver is actually being used.
This allows clients of this package to have less error checks without
loosing correctness.
In addition this PR adds more tests, improves test code coverage, and
makes golinter happy by removing deferred Close call.
This PR adds a new migration source driver capable of reading files from
any source that implements http.FileSystem interface.
Notable http.FileSystem interface implementations:
* http.Dir() - wrapper over local file-system
* github.com/shurcooL/vfsgen
Because user of this package is responsible for getting an
implementation of http.FileSystem, this driver does not support creating
instances from driver URLs.
* Let database.Open() use schemeFromURL as well
Otherwise it will fail on MySQL DSNs.
Moved schemeFromURL into the database package. Also removed databaseSchemeFromURL
and sourceSchemeFromURL as they were just calling schemeFromURL.
Fixes https://github.com/golang-migrate/migrate/pull/265#issuecomment-522301237
* Moved url functions into internal/url
Also merged the test cases.
* Add some database tests to improve coverage
* Fix suggestions
* NewDockerContainer: restore "from env" behavior
commit c31948caeb replaced the deprecated
`dockerclient.NewEnvClient` with `dockerclient.NewClientWithOpts`, but
did not add the `FromEnv` option to keep the old behavior.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* NewDockerContainer: use API version negotiation
This helps in situations where the daemon is older than
the API client. API version negotiation checks the maximum
supported API version by the daemon, and downgrades to that
API version if needed.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Fix in the URL parser with go 1.12.8 and github.com/go-sql-driver/mysql
Change schemeFromURL to just split the url by :// to find the scheme.
It's not required to parse the whole URL. MySQL DSNs aren't valid URLs.
Fixes#264
* The mysql driver itself also used net/url.Parse
* Also fix TestPasswordUnencodedReservedURLChars
* Keep backwards compatibility with url encoded username and passwords
* Fix suggestions
* Reuse old function names
The default exit status when a command cannot be found was 0.
This can cause migrate to fail "silently" in case of typos.
Given that providing an invalid flag causes the program to exit
with a exit status set to 2, the default exit status was also set to 2.
default behaviour for down is to apply all down migrations, which is
comparable to dropping a database - and usually not the desired default
action
proposed changes:
* `down` prompts for a confirm `y` before applying all down migrations, defaulting to doing nothing
* `down --all` does the current behaviour, applying all down migrations
* `down N` is unchanged
* `down N --all` errors
* `down --all N` errors
* Disable FOREIGN_KEY_CHECKS in MySQL when dropping all tables.
* Lowercased system variable
* Discard error enabling foreign_key_checks, dropping is already successful at this point
* Explicitly discard error
- Only compile a regex once for re-use
- Don't use regex unnecessarily (removing trailing semicolon)
- Add test for parsing multiple statements in a migration
* Added Firebird support
* Fixed typo
* Refactoring
* Schema migrations table name don't have to be upper case
* Fixed readme
* Added Firebird 2.5 support
* Removed SchemaName
* Refactoring
* Consistently lock in ensureVersionTable and do not call ensureVersionTable from Drop across all database implementations
* Add test for dropping postgres databases
* Fix failing database tests
* Fix CockroachDb test, lock table should be created before versionTable
* Add Initialize() to Driver interface, and add integration tests for Drop() between database implementations and migrate
* Remove Initialize, document breaking behaviour of Drop
* Revert introduction of Initialize method
* Removed Initialize in Stub as well
* Remove call to non-existent Initialize and make sure to close re-initialized database connections
* Revert changes to TestDrop in database/testing
* Split Test and TestMigrate into different test entrypoints
* Remove unused import in migrate_testing
* Remove erroneous code to fix tests
* Add stub source imports to database tests
* Add Stub source to migrate tests
* Use example migrations for tests
* Add file driver to database tests
* Align database directory layout
* Add file source driver to Cassandra
* Review changes
* Minor syntactic change for cleaner diff
This commit reverts back to querying the existance of the table instead
of using CREATE IF NOT EXISTS because we want to support versions of
Postgres older than 9.1 which is when this feature was introduced.
- Leaving migrate/testing in case there are unknown consumers
- Add migrate/dktesting package
- Update tests to use migrate/dktesting instead of migrate/testing
- Stop leaking tickers. As the docs state, using time.Tick() will leak tickers,
so use time.NewTicker() with time.Ticker.Stop().
- Be more efficient by using time.NewTimer() with time.Timer.Stop() instead of time.After().
There is lock conflict on parallel migrations in different postgres
schemas. To avoid this conflicts function GenerateAdvisoryLockId added
variadic params to change lock id with schema name. Schema name taked
with postgres CURRENT_SCHEMA function. Null byte used as separator
between database and schema name, because any other symbol may be used
in both of it.
Closes#118
This addresses https://github.com/golang-migrate/migrate/issues/90 . The
exported Redshift object no longer exports an embedde 'Driver' however,
so some more work is needed to make this backwards compatible.
Redshift does not support advisory lock functions. The closest
capability is in-transaction table locks, which aren't quite right here
because the transaction scope is established within SetVersion, not
higher up above the Lock-before/Unlock-after SetVersion.
Local locking is left intact to satisfy expected "can't Lock twice
before Unlocking" behavior asserted in shared tests.
Avoid stepping on the 'redshift' driver for the time being. Driver
registration is also modified to identify the clone as 'redshift2'
rather than 'postgres'.
(Install for [MacOS](https://docs.docker.com/docker-for-mac/))
1. Use a version of Go that supports [modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) (e.g. Go 1.11+)
1. Fork this repo and `git clone` somewhere to `$GOPATH/src/github.com/golang-migrate/migrate`
1. Install [dep](https://github.com/golang/dep) and run `dep ensure` to pull dependencies
* Ensure that [Go modules are enabled](https://golang.org/cmd/go/#hdr-Preliminary_module_support) (e.g. your repo path or the `GO111MODULE` environment variable are set correctly)
NilMigration defines a migration without a body. NilVersion is defined as const -1.
#### What is the difference between uint(version) and int(targetVersion)?
version refers to an existing migration version coming from a source and therefor can never be negative.
version refers to an existing migration version coming from a source and therefore can never be negative.
targetVersion can either be a version OR represent a NilVersion, which equals -1.
#### What's the difference between Next/Previous and Up/Down?
@@ -50,10 +50,10 @@
and whenever we want, not just once at the beginning of all tests.
#### Can I maintain my driver in my own repository?
Yes, technically thats possible. We want to encourage you to contribute your driver to this respository though.
Yes, technically thats possible. We want to encourage you to contribute your driver to this repository though.
The driver's functionality is dictated by migrate's interfaces. That means there should really
just be one driver for a database/ source. We want to prevent a future where several drivers doing the exact same thing,
just implemented a bit differently, co-exist somewhere on Github. If users have to do research first to find the
just implemented a bit differently, co-exist somewhere on GitHub. If users have to do research first to find the
"best" available driver for a database in order to get started, we would have failed as an open source community.
#### Can I mix multiple sources during a batch of migrations?
@@ -64,4 +64,16 @@
which prevents attempts to run more migrations on top of a failed migration. You need to manually fix the error
and then "force" the expected version.
#### What happens if two programs try and update the database at the same time?
Database-specific locking features are used by *some* database drivers to prevent multiple instances of migrate from running migrations on
the same database at the same time. For example, the MySQL driver uses the `GET_LOCK` function, while the Postgres driver uses
the `pg_advisory_lock` function.
#### Do I need to create a table for tracking migration version used?
No, it is done automatically.
#### Can I use migrate with a non-Go project?
Yes, you can use the migrate CLI in a non-Go project, but there are probably other libraries/frameworks available that offer better test and deploy integrations in that language/framework.
#### I have got an error `Dirty database version 1. Fix and force version`. What should I do?
Keep calm and refer to [the getting started docs](GETTING_STARTED.md#forcing-your-database-version).
**IMPORTANT:** In a project developed by more than one person there is a chance of migrations inconsistency - e.g. two developers can create conflicting migrations, and the developer that created their migration later gets it merged to the repository first.
Developers and Teams should keep an eye on such cases (especially during code review).
[Here](https://github.com/golang-migrate/migrate/issues/179#issuecomment-475821264) is the issue summary if you would like to read more.
Consider making your migrations idempotent - we can run the same sql code twice in a row with the same result. This makes our migrations more robust. On the other hand, it causes slightly less control over database schema - e.g. let's say you forgot to drop the table in down migration. You run down migration - the table is still there. When you run up migration again - `CREATE TABLE` would return an error, helping you find an issue in down migration, while `CREATE TABLE IF NOT EXISTS` would not. Use those conditions wisely.
In case you would like to run several commands/queries in one migration, you should wrap them in a transaction (if your database supports it).
This way if one of commands fails, our database will remain unchanged.
## Run migrations
Run your migrations through the CLI or your app and check if they applied expected changes.
Just to give you an idea:
```
migrate -database YOUR_DATABASE_URL -path PATH_TO_YOUR_MIGRATIONS up
```
Just add the code to your app and you're ready to go!
Before committing your migrations you should run your migrations up, down, and then up again to see if migrations are working properly both ways.
(e.g. if you created a table in a migration but reverse migration did not delete it, you will encounter an error when running the forward migration again)
It's also worth checking your migrations in a separate, containerized environment. You can find some tools at the [end of this document](#further-reading).
**IMPORTANT:** If you would like to run multiple instances of your app on different machines be sure to use a database that supports locking when running migrations. Otherwise you may encounter issues.
## Forcing your database version
In case you run a migration that contained an error, migrate will not let you run other migrations on the same database. You will see an error like `Dirty database version 1. Fix and force version`, even when you fix the erred migration. This means your database was marked as 'dirty'.
You need to investigate the migration error - was your migration applied partially, or was it not applied at all? Once you know, you should force your database to a version reflecting it's real state. You can do so with `force` command:
```
migrate -path PATH_TO_YOUR_MIGRATIONS -database YOUR_DATABASE_URL force VERSION
```
Once you force the version and your migration was fixed, your database is 'clean' again and you can proceed with your migrations.
For details and example of usage see [this comment](https://github.com/golang-migrate/migrate/issues/282#issuecomment-530743258).
CGO_ENABLED=0 go build -ldflags='-X main.Version=$(VERSION)' -tags '$(DATABASE) $(SOURCE)' ./cmd/migrate
build-docker:
CGO_ENABLED=0 go build -a -o build/migrate.linux-386 -ldflags="-s -w -X main.Version=${VERSION}" -tags "$(DATABASE)$(SOURCE)" ./cmd/migrate
build-cli:clean
-mkdir ./cli/build
cd ./cli&&CGO_ENABLED=0GOOS=linux GOARCH=amd64 go build -a -o build/migrate.linux-amd64 -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cli&&CGO_ENABLED=0GOOS=darwin GOARCH=amd64 go build -a -o build/migrate.darwin-amd64 -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cli&&CGO_ENABLED=0GOOS=windowsGOARCH=amd64 go build -a -o build/migrate.windows-amd64.exe -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cmd/migrate&&CGO_ENABLED=0GOOS=linux GOARCH=amd64 go build -a -o ../../cli/build/migrate.linux-amd64 -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cmd/migrate&&CGO_ENABLED=0GOOS=linux GOARCH=arm GOARM=7 go build -a -o ../../cli/build/migrate.linux-armv7 -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cmd/migrate&&CGO_ENABLED=0GOOS=linuxGOARCH=arm64 go build -a -o ../../cli/build/migrate.linux-arm64 -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cmd/migrate &&CGO_ENABLED=0GOOS=darwin GOARCH=amd64 go build -a -o ../../cli/build/migrate.darwin-amd64 -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cmd/migrate &&CGO_ENABLED=0GOOS=windows GOARCH=386 go build -a -o ../../cli/build/migrate.windows-386.exe -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cmd/migrate &&CGO_ENABLED=0GOOS=windows GOARCH=amd64 go build -a -o ../../cli/build/migrate.windows-amd64.exe -ldflags='-X main.Version=$(VERSION) -extldflags "-static"' -tags '$(DATABASE) $(SOURCE)' .
cd ./cli/build && find . -name 'migrate*'| xargs -I{} tar czf {}.tar.gz {}
[](https://github.com/golang-migrate/migrate/actions/workflows/ci.yaml?query=branch%3Amaster)
Database connection strings are specified via URLs. The URL format is driver dependent but generally has the form: `dbdriver://username:password@host:port/dbname?param1=true¶m2=false`
Any [reserved URL characters](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) need to be escaped. Note, the `%` character also [needs to be escaped](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_the_percent_character)
Explicitly, the following characters need to be escaped:
It's easiest to always run the URL parts of your DB connection URL (e.g. username, password, etc) through an URL encoder. See the example Python snippets below:
```bash
$ python3 -c 'import urllib.parse; print(urllib.parse.quote(input("String to encode: "), ""))'
We prefer [coordinated disclosures](https://en.wikipedia.org/wiki/Coordinated_vulnerability_disclosure). To start one, create a GitHub security advisory following [these instructions](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability)
Please suggest potential impact and urgency in your reports.
dirPtr:=createFlagSet.String("dir","","Directory to place file in (default: current working directory)")
formatPtr:=createFlagSet.String("format",defaultTimeFormat,`The Go time format string to use. If the string "unix" or "unixNano" is specified, then the seconds or nanoseconds since January 1, 1970 UTC respectively will be used. Caution, due to the behavior of time.Time.Format(), invalid format strings will not error`)
createFlagSet.BoolVar(&seq,"seq",seq,"Use sequential numbers instead of timestamps (default: false)")
createFlagSet.IntVar(&seqDigits,"digits",seqDigits,"The number of digits to use in sequences (default: 6)")
$ go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@$TAG
```
#### Unversioned
```bash
$ # Go 1.15 and below
$ go get -tags 'postgres' -u github.com/golang-migrate/migrate/cmd/migrate
$ # Go 1.16+
$ go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
```
#### Notes
1. Requires a version of Go that [supports modules](https://golang.org/cmd/go/#hdr-Preliminary_module_support). e.g. Go 1.11+
1. These examples build the cli which will only work with postgres. In order
to build the cli for use with other databases, replace the `postgres` build tag
with the appropriate database tag(s) for the databases desired. The tags
correspond to the names of the sub-packages underneath the
[`database`](../../database) package.
1. Similarly to the database build tags, if you need to support other sources, use the appropriate build tag(s).
1. Support for build constraints will be removed in the future: https://github.com/golang-migrate/migrate/issues/60
1. For versions of Go 1.15 and lower, [make sure](https://github.com/golang-migrate/migrate/pull/257#issuecomment-705249902) you're not installing the `migrate` CLI from a module. e.g. there should not be any `go.mod` files in your current directory or any directory from your current directory to the root
## Usage
```bash
$ migrate -help
Usage: migrate OPTIONS COMMAND [arg...]
migrate [ -version | -help ]
Options:
-source Location of the migrations (driver://url)
-path Shorthand for -source=file://path
-database Run migrations against this database (driver://url)
-prefetch N Number of migrations to load in advance before executing (default 10)
-lock-timeout N Allow N seconds to acquire database lock (default 15)
-verbose Print verbose logging
-version Print version
-help Print usage
Commands:
create [-ext E][-dir D][-seq][-digits N][-format][-tz] NAME
Create a set of timestamped up/down migrations titled NAME, in directory D with extension E.
Use -seq option to generate sequential up/down migrations with N digits.
Use -format option to specify a Go time format string. Note: migrations with the same time cause "duplicate migration version" error.
Use -tz option to specify the timezone that will be used when generating non-sequential migrations (defaults: UTC).
goto V Migrate to version V
up [N] Apply all or N up migrations
down [N][-all] Apply all or N down migrations
Use -all to apply all down migrations
drop [-f] Drop everything inside database
Use -f to bypass confirmation
force V Set version V but don't run migration (ignores dirty state)
version Print current migration version
```
So let's say you want to run the first two migrations
```bash
$ migrate -source file://path/to/migrations -database postgres://localhost:5432/database up 2
* Drop command will not work on Cassandra 2.X because it rely on
*`Drop()` method will not work on Cassandra 2.X because it rely on
system_schema table which comes with 3.X
* Other commands should work properly but are **not tested**
* Other methods should work properly but are **not tested**
* The Cassandra driver (gocql) does not natively support executing multiple statements in a single query. To allow for multiple statements in a single migration, you can use the `x-multi-statement` param. There are two important caveats:
* This mode splits the migration text into separately-executed statements by a semi-colon `;`. Thus `x-multi-statement` cannot be used when a statement in the migration contains a string with a semi-colon.
* The queries are not executed in any sort of transaction/batch, meaning you are responsible for fixing partial migrations.
**ScyllaDB**
* No additional configuration is required since it is a drop-in replacement for Cassandra.
* The `Drop()` method` works for ScyllaDB 5.1
## Usage
@@ -12,13 +20,19 @@ system_schema table which comes with 3.X
| URL Query | Default value | Description |
|------------|-------------|-----------|
| `x-migrations-table` | schema_migrations | Name of the migrations table |
| `x-multi-statement` | false | Enable multiple statements to be ran in a single migration (See note above) |
| `port` | 9042 | The port to bind to |
| `consistency` | ALL | Migration consistency
| `protocol` | | Cassandra protocol version (3 or 4)
| `timeout` | 1 minute | Migration timeout
| `connect-timeout` | 600ms | Initial connection timeout to the cluster |
| `username` | nil | Username to use when authenticating. |
| `password` | nil | Password to use when authenticating. |
| `sslcert` | | Cert file location. The file must contain PEM encoded data. |
| `sslkey` | | Key file location. The file must contain PEM encoded data. |
| `sslrootcert` | | The location of the root certificate file. The file must contain PEM encoded data. |
| `sslmode` | | Whether or not to use SSL (disable\|require\|verify-ca\|verify-full) |
# CockroachDB tutorial for beginners (insecure cluster)
## Create/configure database
First, let's start a local cluster - follow step 1. and 2. from [the docs](https://www.cockroachlabs.com/docs/stable/start-a-local-cluster.html#step-1-start-the-first-node).
Once you have it, create a database. Here I am going to create a database called `example`.
Our user here is `cockroach`. We are not going to use a password, since it's not supported for insecure cluster.
```
cockroach sql --insecure --host=localhost:26257
```
```
CREATE DATABASE example;
CREATE USER IF NOT EXISTS cockroach;
GRANT ALL ON DATABASE example TO cockroach;
```
When using Migrate CLI we need to pass to database URL. Let's export it to a variable for convenience:
`sslmode=disable` means that the connection with our database will not be encrypted. This is needed to connect to an insecure node.
**NOTE:** Do not use COCKROACH_URL as a variable name here, it's already in use for discrete parameters and you may run into connection problems. For more info check out [docs](https://www.cockroachlabs.com/docs/stable/connection-parameters.html#connect-using-discrete-parameters).
You can find further description of database URLs [here](README.md#database-urls).
If there were no errors, we should have two files available under `db/migrations` folder:
- 000001_create_users_table.down.sql
- 000001_create_users_table.up.sql
Note the `sql` extension that we provided.
In the `.up.sql` file let's create the table:
```
CREATE TABLE IF NOT EXISTS example.users
(
user_id INT PRIMARY KEY,
username VARCHAR (50) UNIQUE NOT NULL,
password VARCHAR (50) NOT NULL,
email VARCHAR (300) UNIQUE NOT NULL
);
```
And in the `.down.sql` let's delete it:
```
DROP TABLE IF EXISTS example.users;
```
By adding `IF EXISTS/IF NOT EXISTS` we are making migrations idempotent - you can read more about idempotency in [getting started](/GETTING_STARTED.md#create-migrations)
## Run migrations
```
migrate -database ${COCKROACHDB_URL} -path db/migrations up
```
Let's check if the table was created properly by running `cockroach sql --insecure --host=localhost:26257 -e "show columns from example.users;"`.
iferr:=d.(*CockroachDb).db.QueryRow("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'bar' AND table_schema = (SELECT current_schema()))").Scan(&exists);err!=nil{
iferr:=d.Run(strings.NewReader("CREATE TABLE foo (foo text); CREATE TABLE bar (bar text);"));err!=nil{
t.Fatalf("expected err to be nil, got %v",err)
}
// make sure second table exists
varexistsbool
iferr:=d.(*CockroachDb).db.QueryRow("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'bar' AND table_schema = (SELECT current_schema()))").Scan(&exists);err!=nil{
Hanzo Datastore is a ClickHouse-wire-compatible database engine. This driver
connects through the native `github.com/hanzo-ds/go` driver, which registers the
`database/sql` driver name `datastore`.
| URL Query | Description |
|------------|-------------|
| `x-migrations-table`| Name of the migrations table |
| `x-migrations-table-engine`| Engine to use for the migrations table, defaults to TinyLog |
| `x-cluster-name` | Name of cluster for creating `schema_migrations` table cluster wide |
| `x-multi-statement` | Enable multiple statements to be ran in a single migration (See note below) |
| `x-multi-statement-max-size` | Maximum size of a single migration in bytes when `x-multi-statement` is set (defaults to 10 MB) |
| `database` | The name of the database to connect to |
| `username` | The user to sign in as |
| `password` | The user's password |
| `host` | The host to connect to. |
| `port` | The port to bind to. |
## Notes
* The Datastore driver does not natively support executing multiple statements in a single query. To allow for multiple statements in a single migration, you can use the `x-multi-statement` param. There are two important caveats:
* This mode splits the migration text into separately-executed statements by a semi-colon `;`. Thus `x-multi-statement` cannot be used when a statement in the migration contains a string with a semi-colon.
* The queries are not executed in any sort of transaction/batch, meaning you are responsible for fixing partial migrations.
* Using the default TinyLog table engine for the `schema_migrations` table prevents backing up the table. If you need to back up the database, run the migrations with `x-migrations-table-engine=MergeTree`.
* Datastore cluster mode is not officially supported, but you can try enabling `schema_migrations` table replication by specifying a `x-cluster-name`:
* When `x-cluster-name` is specified, `x-migrations-table-engine` also should be specified.
* When `x-cluster-name` is specified, only the `schema_migrations` table is replicated across the cluster. You still need to write your migrations so that the application tables are replicated within the cluster.
* If you want to create a database inside a migration, note that the `schema_migrations` table will live in the `default` database, so you cannot use `USE <database_name>` inside a migration. In this case you may omit the database in the connection string (example [here](examples/migrations/003_create_database.up.sql)).
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
* Driver work with mongo through [db.runCommands](https://docs.mongodb.com/manual/reference/command/)
* Migrations support json format. It contains array of commands for `db.runCommand`. Every command is executed in separate request to database
* All keys have to be in quotes `"`
* [Examples](./examples)
# Usage
`mongodb://user:password@host:port/dbname?query` (`mongodb+srv://` also works, but behaves a bit differently. See [docs](https://docs.mongodb.com/manual/reference/connection-string/#dns-seedlist-connection-format) for more information)
| `x-migrations-collection` | `MigrationsCollection` | Name of the migrations collection |
| `x-transaction-mode` | `TransactionMode` | If set to `true` wrap commands in [transaction](https://docs.mongodb.com/manual/core/transactions). Available only for replica set. Driver is using [strconv.ParseBool](https://golang.org/pkg/strconv/#ParseBool) for parsing|
| `x-advisory-locking` | `true` | Feature flag for advisory locking, if set to false, disable advisory locking |
| `x-advisory-lock-collection` | `migrate_advisory_lock` | The name of the collection to use for advisory locking.|
| `x-advisory-lock-timeout` | `15` | The max time in seconds that migrate will wait to acquire a lock before failing. |
| `x-advisory-lock-timeout-interval` | `10` | The max time in seconds between attempts to acquire the advisory lock, the lock is attempted to be acquired using an exponential backoff algorithm. |
| `dbname` | `DatabaseName` | The name of the database to connect to |
| `user` | | The user to sign in as. Can be omitted |
| `password` | | The user's password. Can be omitted |
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table |
| `x-no-lock` | `NoLock` | Set to `true` to skip `GET_LOCK`/`RELEASE_LOCK` statements. Useful for [multi-master MySQL flavors](https://www.percona.com/doc/percona-xtradb-cluster/LATEST/features/pxc-strict-mode.html#explicit-table-locking). Only run migrations from one host when this is enabled. |
| `x-statement-timeout` | `StatementTimeout` | Abort any statement that takes more than the specified number of milliseconds, functionally similar to [Server-side SELECT statement timeouts](https://dev.mysql.com/blog-archive/server-side-select-statement-timeouts/) but enforced by the client. Available for all versions of MySQL, not just >=5.7. |
| `dbname` | `DatabaseName` | The name of the database to connect to |
| `user` | | The user to sign in as |
| `password` | | The user's password |
| `host` | | The host to connect to. |
| `port` | | The port to bind to. |
| `x-tls-ca` | | The location of the root certificate file. |
| `x-tls-cert` | | Certfile location. |
| `x-tls-key` | | Key file location. |
| `tls` | | TLS / SSL encrypted connection parameter; see [go-sql-driver](https://github.com/go-sql-driver/mysql#tls). Use any name (e.g. `migrate`) if you want to use a custom TLS config (`x-tls-` queries). |
| `x-tls-ca` | | The location of the CA (certificate authority) file. |
| `x-tls-cert` | | The location of the client certificate file. Must be used with `x-tls-key`. |
| `x-tls-key` | | The location of the private key file. Must be used with `x-tls-cert`. |
| `x-tls-insecure-skip-verify` | | Whether or not to use SSL (true\|false) |
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.