Contributing to Google Cloud Firestore
Thank you for your interest in making a contribution to google-cloud-ruby. Community contributions are an essential part of open source, and we want to make contributing easy for you. If you have any suggestions for how to improve this guide, please open an issue and let us know!
Code of Conduct
Please note that this project is covered by a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. See Code of Conduct for more information.
Overview
- Open an issue
- Sign Contributor License Agreement
- Set up environment
- Run CI
- Make changes
- Commit changes
- Run CI again
- Submit your pull request
Open an issue
Pull requests should generally be directed by an existing issue, otherwise you risk working on something that the maintainers might not be able to accept into the project. Please take a look through the repository issues, and if you do not see an existing issue for your problem or feature, please open one using one of the provided templates.
Sign Contributor License Agreement
Before we can accept your pull requests you'll need to sign a Contributor License Agreement (CLA):
- If you are an individual writing original source code and you own the intellectual property, then you'll need to sign an individual CLA.
- If you work for a company that wants to allow you to contribute your work, then you'll need to sign a corporate CLA.
You can sign these electronically. After that, we'll be able to accept your pull requests.
Set up environment
Before you start on a pull request, you should prepare your work environment for development, acceptance testing and the interactive console (optional).
Local development setup
To set up your local development environment:
Install a supported version (or versions) of Ruby. (You may choose to manage your Ruby and gem installations with RVM, rbenv, chruby or a similar tool.)
Install Bundler.
$ gem install bundler
- Fork the
google-cloud-ruby repo, clone your fork, and configure the
upstream
remote:
git clone https://github.com/<your-username>/google-cloud-ruby.git
cd google-cloud-ruby
git remote add upstream [email protected]:googleapis/google-cloud-ruby.git
- If your fork and clone are not brand new, get the latest changes from
upstream
:
git checkout main
git pull upstream main
- Change to the library's sub-directory in the repo:
$ cd google-cloud-firestore
- Install (or update) the library dependencies:
$ bundle update
- Create a new topic branch off of the
main
branch:
git checkout -b <topic-branch>
Acceptance tests setup
To set up your acceptance test credentials:
If needed, create a Google Cloud project. In the Google Cloud Console, on the project selector page, select or create a project.
Ensure that billing is enabled for your project.
Ensure that the Firestore API is enabled for your project. Note that if you have already enabled the Datastore API for your project, you will need to use a different project for Firestore.
Follow the instructions for Creating a Service Account in
AUTHENTICATION.md
, including downloading and securely storing a JSON key file.Set the
GCLOUD_TEST_KEYFILE
environment variable to the path of the JSON key file that you downloaded in the previous step:
$ export GCLOUD_TEST_KEYFILE=/path/to/keyfile.json
If you are already using the GCLOUD_TEST_KEYFILE
environment variable, and wish to test this library with a
different key file, you may set the FIRESTORE_TEST_KEYFILE
environment variable instead:
$ export FIRESTORE_TEST_KEYFILE=/path/to/keyfile.json
- Set the
GCLOUD_TEST_PROJECT
environment variable to your Google Cloud project ID:
$ export GCLOUD_TEST_PROJECT=my-project-id
If you are already using the GCLOUD_TEST_PROJECT
environment variable, and wish to test this library with a
different project, you may set the FIRESTORE_TEST_PROJECT
environment variable instead:
$ export FIRESTORE_TEST_PROJECT=my-project-id
Interactive console setup (optional)
To set up your interactive console credentials:
- Set the
GOOGLE_APPLICATION_CREDENTIALS
environment variable to the path of your service account JSON key file (see above):
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/keyfile.json
If you are already using the GOOGLE_APPLICATION_CREDENTIALS
environment variable, and wish to test this library
with a different key file, you may set the FIRESTORE_CREDENTIALS
environment variable instead:
$ export FIRESTORE_CREDENTIALS=/path/to/keyfile.json
- Set the
GOOGLE_CLOUD_PROJECT
environment variable to your Google Cloud project ID:
$ export GOOGLE_CLOUD_PROJECT=my-project-id
If you are already using the GOOGLE_CLOUD_PROJECT
environment variable, and wish to test this library with a
different project, you may set the FIRESTORE_PROJECT
environment variable instead:
$ export FIRESTORE_PROJECT=my-project-id
Run CI
You are now ready to run local CI checks for the library, which you should do before you make any changes. Doing so ensures that everything is OK with your local environment and the latest dependency versions. You don't want any surprises later.
If you haven't already done so, change to the library's sub-directory in the repo:
$ cd google-cloud-firestore
To run the code style checks, documentation tests, and unit tests together, use the ci
task:
$ bundle exec rake ci
To run the command above, plus all acceptance tests, use rake ci:acceptance
or its handy alias, rake ci:a
. Keep in
mind that the acceptance tests typically take longer than the other CI checks and require authentication credentials.
See the Acceptance tests section below for more information.
The Rake tasks aggregated in the commands above can be run individually to streamline your workflow when developing or debugging.
CI check | Command |
---|---|
Static code analysis | rake rubocop |
Documentation tests | rake doctest |
Unit tests | rake test |
Acceptance tests | rake acceptance |
The subsections below describe the individual CI checks.
Static code analysis
The project uses Rubocop configured with the shared googleapis/ruby-style rules to ensure that your code adheres to Google's Ruby style. The style is largely based on The Ruby Style Guide with a few exceptions:
- Avoid parentheses when possible, including in method definitions.
- Use double-quoted strings.
You can check your code against these rules by running the Rubocop Rake task:
$ bundle exec rake rubocop
In the rare case that you need to override the existing Rubocop configuration for this library in order to accommodate your changes, you can do so by updating .rubocop.yml.
Documentation tests
When adding a new feature, you should almost always add one or more in-line documentation code examples demonstrating
the use of the feature, using YARD's
@example
tag. Be sure to write a complete, executable
example that includes the library require
statement and client initialization.
The project uses yard-doctest to execute each sample as a unit test:
$ bundle exec rake doctest
If you add, remove or modify documentation examples, you may need to update the setup for the tests. The fixtures, stubs
and mocks required to run the tests are located in support/doctest_helper.rb. Please note
that much of the setup is matched to its corresponding example by the title of the @example
tag. If you alter an
example's title, you may encounter broken tests.
There are generally no assertions or mock verifications in these tests. They simply check that the examples are syntactically correct and execute against the library source code without error.
Unit tests
The project uses the minitest library, including specs, mocks, minitest-autotest, and minitest-focus.
To run the unit tests:
$ bundle exec rake test
Although the unit tests are intended to run quickly, during development or debugging you may want to isolate one or more
of the tests by placing the focus
keyword just above the test declaration. (See
minitest-focus for details.)
Conformance tests
Conformance tests are a subset of the unit test suite. The generated conformance
tests are based on specifications that are imported from the
firestore
subdirectory in the googleapis/conformance-tests repo to
the conformance
directory. (Currently, the import process involves manually copying the files whenever they are
changed in their source repo.) You should never change conformance test specifications in this repo.
Because the conformance tests are dynamically generated at run time, working with them is more difficult than working
with hand-written tests. If you need execute one or more of these tests in isolation, you can do so by placing the
focus
keyword just above one of the calls to define_method
. This will isolate a subset of the conformance tests. To
isolate a single conformance test within the subset, insert a conditional statement into the test_file.tests.each
loop
near the bottom of the conformance_test.rb
file. In the conditional, call next
unless the current test description
matches the test you want to isolate.
Acceptance Tests
The acceptance tests (a.k.a. integration tests) ensure that the library works correctly against the live service API. To configure your Google Cloud project, see Acceptance tests setup above.
Warning: You may incur charges while running the acceptance tests against your Google Cloud project.
Like the unit tests, the acceptance tests are based on the minitest library, including specs and minitest-focus. Mocks are not generally used in acceptance tests.
Because the acceptance test suite is often time-consuming to run in its entirety, during development or debugging you
may want to isolate one or more of the tests by placing the focus
keyword just above the test declaration. (See
minitest-focus for details.)
To run the acceptance tests:
$ bundle exec rake acceptance
Some acceptance tests may depend on API features that are not yet generally available, and will fail unless your project is added to an internal allowlist. There may also be tests that usually pass but fail occasionally due to issues like eventual consistency. However, please ensure that you do successfully run acceptance tests for any code areas covered by your pull request.
Make changes
All contributions should include new or updated tests to ensure that the contributed code behaves as expected.
When starting work on a new feature, it often makes sense to begin with a basic acceptance test to ensure that the new
feature is present in the live service API and is available to your project. To run your new test exclusively,
temporarily add the focus
keyword just above the test declaration. (See
minitest-focus for details.) Also, the acceptance tests have a retry
mechanism that can sometimes make it hard to see the correct error when things go wrong. To disable retries while
debugging errors, temporarily comment out or remove the run_one_method
method definition in
acceptance/firestore_helper.rb.
When you are done developing, be sure to remove any usages of the focus
keyword from your tests and restore the
run_one_method
method definition if you removed it.
Console
The project includes a Rake task that automatically loads google-cloud-firestore
and its dependencies in IRB. To
configure your Google Cloud project for IRB, see Interactive console setup above.
Warning: You may incur charges while using the library with your Google Cloud project.
If you haven't already done so, change to the library's sub-directory in the repo:
$ cd google-cloud-firestore
The preloaded IRB console can be used as follows:
$ bundle exec rake console
irb(main):001:0> require "google/cloud/firestore"
=> true
irb(main):002:0> firestore = Google::Cloud::Firestore.new
=> #<Google::Cloud::Firestore::Client:0x00007fea21c8b488 @service=Google::Cloud::Firestore::Service(my-project-id)>
irb(main):003:0>
Using the console provides an interactive alternative to acceptance testing that may make it easier to explore usage and debug problems.
Commit changes
Commit your changes using conventional commits, making sure to include the
associated GitHub issue number. Below is an example of a feat
type commit that will result in a semver minor
release. Notice how it is scoped to the short name of the library, contains a bulleted list of public API changes, and
ends with the closes
GitHub keyword. If this is the only new commit in your branch when you open your pull request,
the commit body including the closes
phrase will be copied to your PR description. If you have multiple commits, you
should copy the body of this anchor commit manually to the PR description, so that GitHub will automatically close the
related issue.
git commit -am "feat(firestore): Add my new feature
* Add MyClass#my_method
closes: #123"
The messages for any subsequent commits you may add do not necessarily need to follow the conventional commits format, as these messages will be manually dropped or added as bullet points to the original message when the PR is squashed and merged.
Run CI again
- If you haven't already done so, change to the library's sub-directory in the repo:
$ cd google-cloud-firestore
- Rebase your topic branch on the upstream
main
branch:
git pull --rebase upstream main
- Run the
ci
task:
$ bundle exec rake ci
- Run the
acceptance
task:
$ bundle exec rake acceptance
Ensure that everything is passing in rake ci
and rake acceptance
, or at least that rake ci
is green and you
haven't broken anything new in rake acceptance
, before you open your pull request.
Submit your pull request
- Rebase your topic branch on the upstream
main
branch:
git pull --rebase upstream main
- Push your topic branch to your fork:
git push origin -u
Open a pull request using the first line of your conventional commit as the title, and with the associated GitHub issue in the description. By convention in this project, the assignee of the pull request will be the maintainer who will merge it once it is approved. If you are a maintainer of the project, typically you should assign the pull request to yourself.
Ensure that all of the GitHub checks are passing.