diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..fcf609296b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +# Cut a release whenever a new tag is pushed to the repo. +name: Release + +on: + push: + tags: + - "v*.*.*" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: bazel test //... + env: + # Bazelisk will download bazel to here + XDG_CACHE_HOME: ~/.cache/bazel-repo + run: bazel --bazelrc=.github/workflows/ci.bazelrc --bazelrc=.bazelrc test //... + - name: Prepare workspace snippet + run: .github/workflows/workspace_snippet.sh ${{ env.GITHUB_REF_NAME }} > release_notes.txt + - name: Release + uses: softprops/action-gh-release@v1 + with: + # Use GH feature to populate the changelog automatically + generate_release_notes: true + body_path: release_notes.txt diff --git a/.github/workflows/workspace_snippet.sh b/.github/workflows/workspace_snippet.sh new file mode 100644 index 0000000000..a498d97671 --- /dev/null +++ b/.github/workflows/workspace_snippet.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -o errexit -o nounset -o pipefail + +# Set by GH actions, see +# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables +TAG=${GITHUB_REF_NAME} +PREFIX="rules_python-${TAG:1}" +SHA=$(git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip | shasum -a 256 | awk '{print $1}') + +cat << EOF +WORKSPACE setup: + +\`\`\`starlark +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +http_archive( + name = "rules_python", + sha256 = "${SHA}", + strip_prefix = "${PREFIX}", + url = "https://github.com/bazelbuild/rules_python/archive/${TAG}.tar.gz", +) +\`\`\` +EOF diff --git a/BUILD b/BUILD index f6d68e0450..6ba643c4fd 100644 --- a/BUILD +++ b/BUILD @@ -26,7 +26,7 @@ filegroup( name = "distribution", srcs = [ "BUILD", - "LICENSE", + "WORKSPACE", "internal_deps.bzl", "internal_setup.bzl", "//python:distribution", @@ -34,7 +34,7 @@ filegroup( "//third_party/github.com/bazelbuild/bazel-skylib/lib:distribution", "//tools:distribution", ], - visibility = ["//distro:__pkg__"], + visibility = ["//examples:__pkg__"], ) # Reexport of all bzl files used to allow downstream rules to generate docs diff --git a/DEVELOPING.md b/DEVELOPING.md index e346e95b43..96db780e7e 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -14,23 +14,11 @@ changes still come under the minor-version digit. So releases with API changes a those with only bug fixes and other minor changes bump the patch digit. #### Steps - -1. Update `version.bzl` with the new semantic version `X.Y.Z`. -2. Run `bazel build //distro:rules_python-X.Y.Z` to build the distributed tarball. -3. Calculate the Sha256 hash of the tarball. This hash will be used in the `http_archive` rules that download the new release. - 1. Example command for OSX: `shasum --algorithm 256 bazel-bin/distro/rules_python-0.1.0.tar.gz` -4. Update nested examples in `examples/*/WORKSPACE` to get the new semantic version with the new `sha256` hash. -5. Create commit called "Release X.Y.Z" - 1. ["release 0.1.0"](https://github.com/bazelbuild/rules_python/commit/c8c79aae9aa1b61d199ad03d5fe06338febd0774) is an example commit. -6. Tag that commit as `X.Y.Z`. Eg. `git tag X.Y.Z` -7. Push the commit and the new tag to `main`. -8. Run `bazel build //distro:relnotes` from within workspace and then from repo root run `cat bazel-bin/distro/relnotes.txt` to get the 'install instructions' that are added as release notes. - 1. Check the `sha256` value matches the one you calculated earlier. -9. ["Draft a new release"](https://github.com/bazelbuild/rules_python/releases/new) in Github (manual for now), selecting the recently pushed `X.Y.Z` tag. -Upload the release artifact from `rules_python-[version].tar.gz`. Also copy the `relnotes.txt` from step 8, adding anything extra if desired. +1. Determine what will be the next release, following semver. +1. Create a tag and push, e.g. `git tag 0.5.0 upstream/main && git push upstream --tags` +1. Watch the release automation run on https://github.com/bazelbuild/rules_python/actions #### After release creation in Github -1. Update `README.md` to point at new release. -2. Ping @philwo to get the new release added to mirror.bazel.build. See [this comment on issue #400](https://github.com/bazelbuild/rules_python/issues/400#issuecomment-779159530) for more context. -3. Announce the release in the #python channel in the Bazel slack (bazelbuild.slack.com). +1. Ping @philwo to get the new release added to mirror.bazel.build. See [this comment on issue #400](https://github.com/bazelbuild/rules_python/issues/400#issuecomment-779159530) for more context. +1. Announce the release in the #python channel in the Bazel slack (bazelbuild.slack.com). diff --git a/README.md b/README.md index 0557e859f4..54d18e36bb 100644 --- a/README.md +++ b/README.md @@ -36,18 +36,10 @@ contribute](CONTRIBUTING.md) page for information on our development workflow. ## Getting started To import rules_python in your project, you first need to add it to your -`WORKSPACE` file: +`WORKSPACE` file, using the snippet provided in the +[release you choose](https://github.com/bazelbuild/rules_python/releases) -```python -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -http_archive( - name = "rules_python", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz", - sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332", -) -``` - -To depend on a particular unreleased version (not recommended), you can do: +To depend on a particular unreleased version, you can do: ```python load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") diff --git a/distro/BUILD b/distro/BUILD deleted file mode 100644 index 1d88d32fd0..0000000000 --- a/distro/BUILD +++ /dev/null @@ -1,30 +0,0 @@ -load("@rules_pkg//:pkg.bzl", "pkg_tar") -load("@rules_pkg//releasing:defs.bzl", "print_rel_notes") -load("@rules_python//:version.bzl", "version") - -package( - default_visibility = ["//visibility:private"], -) - -# Build the artifact to put on the github release page. -pkg_tar( - name = "rules_python-%s" % version, - srcs = [ - "//:distribution", - ], - extension = "tar.gz", - # It is all source code, so make it read-only. - mode = "0444", - # Make it owned by root so it does not have the uid of the CI robot. - owner = "0.0", - package_dir = ".", - strip_prefix = ".", - visibility = ["//examples:__pkg__"], -) - -print_rel_notes( - name = "relnotes", - outs = ["relnotes.txt"], - repo = "rules_python", - version = version, -) diff --git a/examples/pip_install/WORKSPACE b/examples/pip_install/WORKSPACE index 42ff327be3..bde77c4171 100644 --- a/examples/pip_install/WORKSPACE +++ b/examples/pip_install/WORKSPACE @@ -11,10 +11,9 @@ http_archive( ], ) -http_archive( +local_repository( name = "rules_python", - sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz", + path = "../..", ) load("@rules_python//python:pip.bzl", "pip_install") diff --git a/examples/pip_parse/WORKSPACE b/examples/pip_parse/WORKSPACE index 6c18864661..be1c8c745e 100644 --- a/examples/pip_parse/WORKSPACE +++ b/examples/pip_parse/WORKSPACE @@ -1,11 +1,8 @@ workspace(name = "example_repo") -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( +local_repository( name = "rules_python", - sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz", + path = "../..", ) load("@rules_python//python:pip.bzl", "pip_parse") diff --git a/examples/py_import/WORKSPACE b/examples/py_import/WORKSPACE index bc325a9132..9fead7b75d 100644 --- a/examples/py_import/WORKSPACE +++ b/examples/py_import/WORKSPACE @@ -1,11 +1,8 @@ workspace(name = "py_import") -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( +local_repository( name = "rules_python", - sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz", + path = "../..", ) load("@rules_python//python:pip.bzl", "pip_install") diff --git a/examples/relative_requirements/WORKSPACE b/examples/relative_requirements/WORKSPACE index 4c635b4c57..0f2da3131c 100644 --- a/examples/relative_requirements/WORKSPACE +++ b/examples/relative_requirements/WORKSPACE @@ -1,11 +1,8 @@ workspace(name = "example_repo") -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( +local_repository( name = "rules_python", - sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz", + path = "../..", ) load("@rules_python//python:pip.bzl", "pip_install") diff --git a/tools/bazel_integration_test/bazel_integration_test.bzl b/tools/bazel_integration_test/bazel_integration_test.bzl index 7fcace650b..84958a4c97 100644 --- a/tools/bazel_integration_test/bazel_integration_test.bzl +++ b/tools/bazel_integration_test/bazel_integration_test.bzl @@ -1,6 +1,6 @@ "Define a rule for running bazel test under Bazel" -load("//:version.bzl", "SUPPORTED_BAZEL_VERSIONS", "version") +load("//:version.bzl", "SUPPORTED_BAZEL_VERSIONS") load("//python:defs.bzl", "py_test") BAZEL_BINARY = "@build_bazel_bazel_%s//:bazel_binary" % SUPPORTED_BAZEL_VERSIONS[0].replace(".", "_") @@ -19,10 +19,6 @@ It is assumed by the test runner that the bazel binary is found at label_workspa Note that if a command contains a bare `--` argument, the --test_arg passed to Bazel will appear before it. """, ), - "distro": attr.label( - allow_single_file = True, - doc = "the .tar.gz distribution file of rules_python to test", - ), "workspace_files": attr.label( doc = """A filegroup of all files in the workspace-under-test necessary to run the test.""", ), @@ -55,14 +51,12 @@ You probably need to run {{ "workspaceRoot": "{TMPL_workspace_root}", "bazelBinaryWorkspace": "{TMPL_bazel_binary_workspace}", - "bazelCommands": [ {TMPL_bazel_commands} ], - "distro": "rules_python/{TMPL_distro_path}" + "bazelCommands": [ {TMPL_bazel_commands} ] }} """.format( TMPL_workspace_root = ctx.files.workspace_files[0].dirname, TMPL_bazel_binary_workspace = ctx.attr.bazel_binary.label.workspace_name, TMPL_bazel_commands = ", ".join(["\"%s\"" % s for s in ctx.attr.bazel_commands]), - TMPL_distro_path = ctx.file.distro.short_path, ), ) @@ -99,7 +93,6 @@ def bazel_integration_test(name, **kwargs): _config( name = "_%s_config" % name, workspace_files = workspace_files, - distro = "//distro:rules_python-%s" % version, ) py_test( @@ -110,7 +103,7 @@ def bazel_integration_test(name, **kwargs): deps = [Label("//python/runfiles")], data = [ BAZEL_BINARY, - "//distro:rules_python-%s.tar.gz" % version, + "//:distribution", "_%s_config" % name, workspace_files, ], diff --git a/tools/bazel_integration_test/test_runner.py b/tools/bazel_integration_test/test_runner.py index df7e528deb..eb5cabdc28 100644 --- a/tools/bazel_integration_test/test_runner.py +++ b/tools/bazel_integration_test/test_runner.py @@ -12,31 +12,6 @@ r = runfiles.Create() - -def modify_WORKSPACE(wksp, distro_path): - """Update the WORKSPACE file in the example to point to our locally-built tar.gz - This allows users to clone rules_python, cd into the example/dir, and run the example directly, - while our integration tests use the locally-built copy. - - Args: - wksp: filesystem absolute path of the bazel WORKSPACE file under test - distro_path: runfiles path of the distro .tar.gz - """ - with open(wksp, "r") as wksp_file: - content = wksp_file.read() - # Replace the url for rules_python with our locally built one - content = re.sub( - r'url = "https://github.com/bazelbuild/rules_python/[^"]+"', - 'url = "file://%s"' % r.Rlocation(distro_path), - content, - ) - # comment out sha256 and strip_prefix if present - content = re.sub(r'sha256 = "', "#\1", content) - content = re.sub(r'strip_prefix = "', "#\1", content) - with open(wksp, "w") as wksp_file: - wksp_file.write(content) - - def main(conf_file): with open(conf_file) as j: config = json.load(j) @@ -58,17 +33,11 @@ def main(conf_file): print("copying workspace under test %s to %s" % (workspacePath, workdir)) shutil.copytree(workspacePath, workdir) - modify_WORKSPACE(os.path.join(workdir, "WORKSPACE"), config["distro"]) - - for command in config["bazelCommands"]: - bazel_args = command.split(" ") - try: - doubleHyphenPos = bazel_args.index("--") - print("patch that in ", doubleHyphenPos) - except ValueError: - pass + for command in config['bazelCommands']: + bazel_args = command.split(' ') + bazel_args.append("--override_repository=rules_python=%s/rules_python" % os.environ['TEST_SRCDIR']) - # Bazel's wrapper script needs this or you get + # Bazel's wrapper script needs this or you get # 2020/07/13 21:58:11 could not get the user's cache directory: $HOME is not defined os.environ["HOME"] = str(Path.home()) diff --git a/version.bzl b/version.bzl index add52f35f0..bc1ccdf43c 100644 --- a/version.bzl +++ b/version.bzl @@ -11,9 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""The version of rules_python.""" - -version = "0.5.0" +"""Versions of rules_python dependencies.""" # Currently used Bazel version. This version is what the rules here are tested # against.