Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create pantsbuild BUILD files with ./pants tailor :: #5738

Merged
merged 6 commits into from
Oct 3, 2022
Merged

Conversation

cognifloyd
Copy link
Member

@cognifloyd cognifloyd commented Sep 20, 2022

Background

This is another part of introducing pants, as discussed in the TSC Meetings on 12 July 2022, 02 Aug 2022 and 06 Sept 2022. Pants has fine-grained per-file caching of results for lint, fmt (like black), test, etc. It also has lockfiles that work well for monorepos that have multiple python packages. With these lockfiles CI should not break when any of our dependencies or our transitive dependencies release new versions, because CI will continue to use the locked version until we explicitly relock with updates.

To keep PRs as manageable/reviewable as possible, introducing pants will take a series of PRs. I do not know yet how many PRs; I will break this up into logical steps with these goals:

  • introduce pants to the st2 repo, and
  • teach some (but not all) TSC members about pants step-by-step.

Other pants PRs include:

Overview of this PR

This PR does 3 things:

I will describe the generated BUILD file contents after I have briefly discussed each of them (the 3 things this PR does).

./pants tailor ::

All but one of the BUILD files in this PR were created by running ./pants tailor :: which is step 5 of the initial config docs.

As described in #5732, BUILD files are an important part of helping pants understand our codebase. As the docs say:

BUILD files provide metadata about your code (the timeout of a test, any dependencies which cannot be inferred, etc). BUILD files are typically located in the same directory as the code they describe. Unlike many other systems, Pants BUILD files are usually very succinct, as most metadata is either inferred from static analysis, assumed from sensible defaults, or generated for you.

In follow-up PRs, we will customize the BUILD metadata further.

GHA workflow

This PR also enables the GHA workflow added in #5732 (it also fixes a typo in the workflow. oops). This workflow will ensure that we have all the BUILD files that pants needs. This is very quick, and serves as an indicator on PRs that people might need to run ./pants tailor ::.

git submodule: test_content_version fixture pack

./pants tailor tried to add BUILD files in the git submodule. But, we cannot guarantee that git submodule is checked out when we run ./pants. So, I added some targets in the parent directory's BUILD file that covers everything in the git submodule. This way, even if the submodule is not checked out, the complete set of metadata is available for pants.

I wrote a plugin for pants that makes the developer UX even better. It checks to make sure the git submodule is checked out, and if not, it provides an error message with instructions on how to fix it. I will submit that in a later PR.

BUILD file metadata

BUILD files contain metadata that guide pants through our source code. That metadata consists of "targets" with "fields".

From the docs: https://www.pantsbuild.org/docs/targets

Targets are an addressable set of metadata describing your code.

Each target type has different fields, or individual metadata values.

One of the nice things about BUILD files, is that they are essentially just python files. In fact, ./pants update-build-files :: actually uses black to reformat them!

So, when looking at BUILD files, defining a target looks like a function call, and the fields are args and/or kwargs in that function call.

There are some restrictions on what python we can use in BUILD files. For example: there are no imports (Pants actually adds all of the required symbols based on which backends are enabled in pants.toml). When we need to add custom targets, we can do that with macros and pants plugins, both of which are also written in python. I have written both macros and pants plugins to add in follow-up PRs.

Targets

These are the targets that ./pants tailor :: added in this PR (linked to the relevant docs page):

I also added some of these:

Tailor cannot add resources or files targets, so those will be added manually in follow-up PRs.

@cognifloyd cognifloyd added this to the pants milestone Sep 20, 2022
@cognifloyd cognifloyd self-assigned this Sep 20, 2022
@pull-request-size pull-request-size bot added the size/L PR that changes 100-499 lines. Requires some effort to review. label Sep 20, 2022
@cognifloyd cognifloyd force-pushed the pants-tailor branch 2 times, most recently from 019cbdc to 0169ed1 Compare September 20, 2022 21:27
@@ -42,11 +40,12 @@ jobs:
# Otherwise, we may need an additional workflow or job to delete old caches
# if they are not expiring fast enough, and we hit the GHA 10GB per repo max.
with:
base-branch: master
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The action defaults to using main as the base-branch (which I forgot, oops).

# To ignore a bad cache, bump the cache* integer.
gha-cache-key: cache0-BUILD
# This hash should include all of our lockfiles so that the pip/pex caches
# get invalidated on any transitive dependency update.
named-caches-hash: ${{ hashFiles('requirements.txt' }}
named-caches-hash: ${{ hashFiles('requirements.txt') }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh! Typo!

Comment on lines +5 to +7
python_test_utils(
name="test_utils0",
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for conftest.py. I will rename the targets in this BUILD file (and others) in a follow-up PR.

Comment on lines +1 to +31
# The files in test_content_version* targets are in ./test_content_version
# which is a git submodule.
# The test_content_version* targets are dependencies of ./test_content_version_fixture

resources(
name="test_content_version_metadata",
sources=[
"test_content_version/pack.yaml",
"test_content_version/**/*.yaml",
"test_content_version/icon.png",
"test_content_version/requirements.txt",
],
)

shell_sources(
name="test_content_version_shell",
sources=[
"test_content_version/**/*.sh",
],
)

python_sources(
name="test_content_version",
dependencies=[
":test_content_version_metadata",
":test_content_version_shell",
],
sources=[
"test_content_version/**/*.py",
],
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the targets that cover the test_content_version git submodule.

Comment on lines +1 to +3
python_sources(
dependencies=["st2tests/st2tests/fixtures/packs:test_content_version"],
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This manually declared dependency tells pants that fixture.py in this directory actually needs the files from test_content_version (the git submodule).

@@ -133,7 +133,7 @@ def test_get_pack_files_and_pack_file_ref_doesnt_equal_pack_name(self):
# Ref is not equal to the name, controller should still work
resp = self.app.get("/v1/packs/views/files/dummy_pack_16")
self.assertEqual(resp.status_int, http_client.OK)
self.assertEqual(len(resp.json), 3)
self.assertEqual(len(resp.json), 4)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to bump the file count in the pack because this PR added a BUILD file in the pack.

@cognifloyd cognifloyd marked this pull request as ready for review September 21, 2022 05:24
@cognifloyd cognifloyd requested review from rush-skills, amanda11, arm4b, nzlosh and a team September 21, 2022 05:24
Copy link

@Eric-Arellano Eric-Arellano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI from our docs about why we recommend doing things this way with one BUILD file per directory:

We've found that it usually scales much better to use a single BUILD file per directory. Even if you start with using the defaults for everything, projects usually need to change some metadata over time, like adding a timeout to a test file or adding dependencies on resources.

It's useful for metadata to be as fine-grained as feasible, such as by using the overrides field to only change the files you need to. Fine-grained metadata is key to having smaller cache keys (resulting in more cache hits), and allows you to more accurately reflect the status of your project. We have found that using one BUILD file per directory encourages fine-grained metadata by defining the metadata adjacent to where the code lives.

Copy link
Contributor

@winem winem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another great job!

@cognifloyd cognifloyd merged commit eeddc49 into master Oct 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
infrastructure: ci/cd maintenance pantsbuild size/L PR that changes 100-499 lines. Requires some effort to review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants