-
Notifications
You must be signed in to change notification settings - Fork 21
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
Initial contribution of code from aspect-build/bazel_rules_template #1
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks for putting it together.
@@ -0,0 +1,13 @@ | |||
# Bazel settings that apply to this repository. | |||
# Take care to document any settings that you expect users to apply. | |||
# Settings that apply only to CI are in .github/workflows/ci.bazelrc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are your thoughts on leveraging Bazel's --config
capability? It allows all of the *.bazelrc
files to live in a single spot. They then can be enabled with the --config
flag. I use it in rules_spm
: ci.bazelrc, enable for CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I've used that --config=ci
scheme in the past as well. The main reason to make another file is because in a complex CI setup, you end up calling bazel
in lots of different places. You need to query things to discover what to build & test, someone's code requires a different configuration (test fails without -c opt
for example).
It's easy to accidentally forget the --config=ci
flag in one of the many invocations of bazel, or especially hard to ensure that later maintainers of the CI scripts don't omit it.
So, the pattern I usually use is to copy the ci.bazelrc file into the system or user's location at the beginning of the pipeline. This way the CI rc settings are always applied without needing to remember what flags to pass each bazel call.
To be fair, in this repo, I don't think it makes much difference which we pick. If we want to simplify things, I wouldn't even bother with a separate rc file, just use the ci
config in the same .bazelrc
with the rest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference is to keep all the CI configuration adjacent, more strongly than to keep all the bazelrc's adjacent. I'm open to discussion on it of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's easy to accidentally forget the
--config=ci
flag in one of the many invocations of bazel, or especially hard to ensure that later maintainers of the CI scripts don't omit it.So, the pattern I usually use is to copy the ci.bazelrc file into the system or user's location at the beginning of the pipeline. This way the CI rc settings are always applied without needing to remember what flags to pass each bazel call.
IIUC the same can be achieved by using build:ci
etc. in .bazelrc
and then writing user.bazelrc
or ~/.bazelrc
with the following contents at the beginning of the CI pipeline.
build --config=ci
query --config=ci
...
.github/workflows/ci.yaml
Outdated
steps: | ||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it | ||
- uses: actions/checkout@v2 | ||
- uses: bazelbuild/setup-bazelisk@v1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? I am able to use Bazelisk without a special setup step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, you showed me that surprisingly GitHub Actions base images already have bazelisk
I'll update the README on this setup-bazelisk thing to indicate that it's optional and drop this line.
bazelbuild/setup-bazelisk@main...alexeagle:patch-1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dropped it
- id: buildifier | ||
- id: buildifier-lint | ||
# Enforce that commit messages allow for later changelog generation | ||
- repo: https://github.com/commitizen-tools/commitizen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not used commitizen
or prettier
. However, I wonder if this should be part of the template. For instance, I tend to commit often during development with varying degrees of useful commit messages. I then do a squash commit when the PR is merged to main. The squash commit is where I spend time crafting a useful message. As this config stands, would the developer be forced to create "meaningful" commit messages for every commit on their branches?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure that commitizen should be part of the setup, so that contributors remember to indicate fix/feature/breaking change. Otherwise it's so hard to determine next release version.
It will remind you about the --no-verify
option whenever it fails, so when I'm doing quick hacking like that I just add the option.
BUILD.bazel
Outdated
) | ||
|
||
# This declares the release artifact users | ||
pkg_tar( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have seen a couple of discussions about whether a release package declaration is necessary. For my repos, I have relied on Github supporting https://github.com/cgrindel/rules_xxx/archive/v0.1.0.tar.gz
. This along with the SHA256 value seems sufficient. Are there good arguments against this practice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, see discussion here
bazel-contrib/SIG-rules-authors#11 (comment)
It's both to get a stable SHA that you can predict ahead-of-time (so the WORKSPACE snippet can be updated in the release process for example) and also to ensure users don't install your tests and examples and docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay got this resolved, now the release automation works without it :)
Thanks @aherrmann
@@ -0,0 +1,113 @@ | |||
"""Create a repository to hold the toolchains |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if toolchains should be included in the default repo structure. Of all the Bazel rule repositories that I have implemented, I only need toolchain stuff for one of them. Perhaps we can leave this as documentation or a separate template?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree, in using this template a lot of the work is correctly removing all the toolchain bits you don't need.
However I think if we just document what to do, it will be hard to follow how to create a toolchain, and we'll end up with a lot of "code in comments" which is harder to keep it working.
If we make a separate template, they will diverge over time and we'll double the maintenance effort.
There are fancy systems for code templating like "cookiecutter" from python-land, where you can interactively ask the user what features to enable, but I don't think the SIG has time to invest in something fancier than just GitHub templates built-in feature.
So I'm torn about what is the better way to do this.
|
||
# The integrity hashes can be computed with | ||
# shasum -b -a 384 [downloaded file] | awk '{ print $1 }' | xxd -r -p | base64 | ||
TOOL_VERSIONS = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand how this is being used. Can you provide more detail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's mirrored from the upstream, providing the bazel downloader with info it needs to place these in the download cache
Co-authored-by: Andreas Herrmann <andreash87@gmx.ch>
Co-authored-by: Andreas Herrmann <andreash87@gmx.ch>
Co-authored-by: Andreas Herrmann <andreash87@gmx.ch>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start! I fully expect this template to evolve over time, so let's not try to be perfect right from the beginning. Feel free to address any of my nits in follow-ups.
load("@rules_pkg//:pkg.bzl", "pkg_tar") | ||
load("@bazel_gazelle//:def.bzl", "gazelle", "gazelle_binary") | ||
|
||
gazelle_binary( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm in favor of adding gazelle as a dependency to virtually all rule sets. It's super nice to have it, but it also pulls in a ton of stuff that rules definitely don't want to be part of their release artifacts. Maybe it would be better to run this in a lint step on CI and print the produced diff that users would need to pass. You'd likely want the lint step in any case to ensure that it's out of sync (I don't use gazelle myself, so not sure if there's a "gazelle lint" command. if it doesn't exist, we should make it happen IMO)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gazelle dependency isn't exposed to users. Nothing in this package is loaded by them.
(In my original formulation we wouldn't even ship this file to users, but @aherrmann convinced me that the GH archive of the repo works)
WORKSPACE
Outdated
@@ -0,0 +1,40 @@ | |||
# Declare the local Bazel workspace. | |||
# This is *not* included in the published distribution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, the release tarball should contain a WORKSPACE file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bazel ignores the WORKSPACE that you include.
But, I've removed the release tarball anyhow.
@@ -0,0 +1,40 @@ | |||
# Declare the local Bazel workspace. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename to WORKSPACE.bazel
for consistency with BUILD
files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's a bug with WORKSPACE.bazel - I can track it down if you like. We had to give up on it for all clients so far.
# so that the dependency on stardoc doesn't leak to them. | ||
load("@aspect_bazel_lib//lib:docs.bzl", "stardoc_with_diff_test", "update_docs") | ||
|
||
stardoc_with_diff_test( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has this rule been fixed on Windows? If not, please add at least a warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule works on windows, but I think you mean the underlying bazel-skylib diff_test being broken on windows at some recent commit?
mylang/private/BUILD.bazel
Outdated
|
||
filegroup( | ||
name = "package_content", | ||
srcs = glob([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you intentionally not including the BUILD
file here?
|
||
# Add more platforms as needed to mirror all the binaries | ||
# published by the upstream project. | ||
PLATFORMS = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be exported from the file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not, but I've often needed to access it somewhere else that wants to loop over them
_DOC = "Fetch external tools needed for mylang toolchain" | ||
_ATTRS = { | ||
"mylang_version": attr.string(mandatory = True, values = TOOL_VERSIONS.keys()), | ||
"platform": attr.string(mandatory = True, values = PLATFORMS.keys()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer setting a sane default here so that not every user has to specify it when using the rules?
Also, I think platform here is a bit of an anti-pattern. IMO, we should add+register toolchains for all platforms and let Bazel select the right toolchain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
users don't typically call this rule themselves. this is inside the loop that creates each platform-specific toolchain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think platform here is a bit of an anti-pattern. IMO, we should add+register toolchains for all platforms and let Bazel select the right toolchain.
As I understand the code that is what it does in the loop below.
Another important bit is also documented here:
Users can avoid this macro and do these steps themselves, if they want more control.
I.e. users should be able to provide their own toolchains with their own platform constraints.
# Remaining content of the file is only used to support toolchains. | ||
######## | ||
_DOC = "Fetch external tools needed for mylang toolchain" | ||
_ATTRS = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a style perspective, I prefer to define attrs
inline in the rule definition (unless they are common attrs
that are used by many rules).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've enjoyed the order of reading the file that starts with the docstring, then the public API. it's more like reading a function in Java where you have the Javadoc, then the params, then the implementation.
But I don't care that much, can go with yours
@aherrmann @cgrindel @Yannic sorry for the delay, I finally got around to trying the pure-GH-archive approach for releases, still adds the WORKSPACE snippet to the release notes automatically just by pushing a tag. PTAL :) |
@alexeagle Just looked at the pure-GH-archive changes. Very cool. I am going to incorporate it into my repositories, this week. |
Thank you, looks good! |
Upstreaming this code to the SIG, since that group is more qualified to recommend how new rulesets are formed.