diff --git a/.factory/automation.yml b/.factory/automation.yml index 7a44c98e..d5d56e81 100644 --- a/.factory/automation.yml +++ b/.factory/automation.yml @@ -1,7 +1,7 @@ build: correctness: build: - image: vaticle-ubuntu-22.04 + image: typedb-ubuntu-22.04 type: foreground command: | bazel build //... diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f2fd8080..994b9cc4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,9 +1,7 @@ -Please replace every line in curly brackets ( { like this } ) with an appropriate description, and remove this line. +## Usage and product changes -## What is the goal of this PR? -{ Please describe the goal of this PR, why they are valuable to achieve, and reference the related GitHub issues. } +## Motivation -## What are the changes implemented in this PR? -{ Please explain what you implemented, why your changes are the best way to achieve the goal(s) above, and reference the GitHub issues to be automatically closed, such like 'closes #number'. } +## Implementation diff --git a/BUILD b/BUILD index 121a8b91..a90c0184 100644 --- a/BUILD +++ b/BUILD @@ -32,6 +32,7 @@ stardoc( "//brew:lib", "//common:lib", "//crates:lib", + "//docs:lib", "//gcp:lib", "//github:lib", "//maven:lib", @@ -40,7 +41,6 @@ stardoc( "//npm/deploy:lib", "//packer:lib", "//pip:lib", - "//rpm:lib", ], symbol_names = [ # From: //apt:rules.bzl @@ -77,6 +77,10 @@ stardoc( "assemble_crate", "deploy_crate", + # From: //docs:*/rules.bzl + "doxygen_docs", + "sphinx_docs", + # From: //gcp:rules.bzl "assemble_gcp", @@ -101,9 +105,5 @@ stardoc( # From: //pip:rules.bzl "assemble_pip", "deploy_pip", - - # From: //rpm:rules.bzl - "assemble_rpm", - "deploy_rpm", ], ) diff --git a/LICENSE b/LICENSE index 6c001179..f433b1a5 100644 --- a/LICENSE +++ b/LICENSE @@ -175,28 +175,3 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Vaticle. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - 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. \ No newline at end of file diff --git a/NOTICE b/NOTICE deleted file mode 100644 index f3bcf1e4..00000000 --- a/NOTICE +++ /dev/null @@ -1,4 +0,0 @@ -Vaticle Bazel Distribution -Copyright (C) 2022 Vaticle - -This product includes software developed at Vaticle (http://vaticle.com/) diff --git a/README.md b/README.md index 842c351b..b57541fe 100755 --- a/README.md +++ b/README.md @@ -275,9 +275,9 @@ deploy_npm(name, re ## How to generate an auth token ### Using the command line (`npm adduser`) - 1. Run `npm adduser <repo_url>` (example: `npm adduser --registry=https://repo.vaticle.com/repository/npm-private`) + 1. Run `npm adduser <repo_url>` (example: `npm adduser --registry=https://npm.cloudsmith.io/typedb/private/`) 2. When prompted, provide login credentials to sign in to the user account that is used in your CI and has permissions to publish the package - 3. If successful, a line will be added to your `.npmrc` file (`$HOME/.npmrc` on Unix) which looks like: `//repo.vaticle.com/repository/npm-snapshot/:_authToken=NpmToken.00000000-0000-0000-0000-000000000000`. The token is the value of `_authToken`, in this case `NpmToken.00000000-0000-0000-0000-000000000000`. + 3. If successful, a line will be added to your `.npmrc` file (`$HOME/.npmrc` on Unix) which looks like: `//npm.cloudsmith.io/typedb/private/:_authToken=NpmToken.00000000-0000-0000-0000-000000000000`. The token is the value of `_authToken`, in this case `NpmToken.00000000-0000-0000-0000-000000000000`. 4. Save the auth token somewhere safe and then delete it from your `.npmrc` file ### Using a UI @@ -321,28 +321,30 @@ Execute Packer to perform deployment | target | assemble_packer label to be deployed. | Label | optional | None | - + -## deploy_rpm +## doxygen_docs
-deploy_rpm(name, release, snapshot, target)
+doxygen_docs(name, desc, main_page_md, project_name, sources, strip_prefix, version)
 
-Deploy package built with `assemble_rpm` to RPM repository. - Select deployment to `snapshot` or `release` repository with `bazel run //:some-deploy-rpm -- [snapshot|release] - + Creates HTML documentation for C++ projects using Doxygen. + **ATTRIBUTES** | Name | Description | Type | Mandatory | Default | | :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| release | Remote repository to deploy rpm release to | String | required | | -| snapshot | Remote repository to deploy rpm snapshot to | String | required | | -| target | assemble_rpm target to deploy | Label | optional | None | +| name | A unique name for this target. | Name | required | | +| desc | A description for the project | String | optional | "" | +| main_page_md | The file to use as main page for the generate docs | Label | optional | None | +| project_name | The project name for the doxygen docs | String | required | | +| sources | A list of files made available to doxygen. This is NOT automatically included in the doxyfile | List of labels | required | | +| strip_prefix | Prefix to strip from path of files being processed | String | optional | "" | +| version | The version of the project being documented | String | optional | "" | @@ -370,7 +372,8 @@ Fills in JSON template with provided values ## java_deps
-java_deps(name, java_deps_root, java_deps_root_overrides, maven_name, target, version_file)
+java_deps(name, allowed_conflicting_jars, ignore_missing_maven_name, java_deps_root,
+          java_deps_root_overrides, maven_name, target, version_file)
 
Packs Java library alongside with its dependencies into archive @@ -381,6 +384,8 @@ Packs Java library alongside with its dependencies into archive | Name | Description | Type | Mandatory | Default | | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | +| allowed_conflicting_jars | List of allowed JAR names that can conflict (ie. the same JAR name produced by two different dependencies). | List of strings | optional | [] | +| ignore_missing_maven_name | Don't fail if bundling using maven names when encountering a target that is missing a maven name | Boolean | optional | False | | java_deps_root | Folder inside archive to put JARs into | String | optional | "" | | java_deps_root_overrides | JARs with filenames matching the given patterns will be placed into the specified folders inside the archive, instead of the default folder. Patterns can be either the full name of a JAR, or a prefix followed by a '*'. | Dictionary: String -> String | optional | {} | | maven_name | Name JAR files inside archive based on Maven coordinates | Boolean | optional | False | @@ -388,6 +393,31 @@ Packs Java library alongside with its dependencies into archive | version_file | File containing version string. Alternatively, pass --define version=VERSION to Bazel invocation. Not specifying version at all defaults to '0.0.0' | Label | optional | None | + + +## sphinx_docs + +
+sphinx_docs(name, out, package_subdir, sphinx_conf, sphinx_rst, target)
+
+ + + Creates an HTML documentation for python module using Sphinx. + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| out | Output directory | Label | required | | +| package_subdir | Directory with the module files in the package archive | String | required | | +| sphinx_conf | Configuration file for the Sphinx documentation builder | Label | required | | +| sphinx_rst | Sphinx documentation master file for the package | Label | required | | +| target | Package including .tar.gz archive | Label | required | | + + ## tgz2zip @@ -597,36 +627,6 @@ Assemble files for HashiCorp Packer deployment | files | Files to include into deployment | {} | - - -## assemble_rpm - -
-assemble_rpm(name, package_name, spec_file, version_file, workspace_refs, installation_dir,
-             archives, empty_dirs, files, permissions, symlinks, tags)
-
- -Assemble package for installation with RPM - -**PARAMETERS** - - -| Name | Description | Default Value | -| :------------- | :------------- | :------------- | -| name | A unique name for this target. | none | -| package_name | Package name for built .rpm package | none | -| spec_file | The RPM spec file to use | none | -| version_file | File containing version number of a package. Alternatively, pass --define version=VERSION to Bazel invocation. Not specifying version defaults to '0.0.0' | None | -| workspace_refs | JSON file with other Bazel workspace references | None | -| installation_dir | directory into which .rpm package is unpacked at installation | None | -| archives | Bazel labels of archives that go into .rpm package | [] | -| empty_dirs | list of empty directories created at package installation | [] | -| files | mapping between Bazel labels of archives that go into .rpm package and their resulting location on .rpm package installation | {} | -| permissions | mapping between paths and UNIX permissions | {} | -| symlinks | mapping between source and target of symbolic links created at installation | {} | -| tags | additional tags passed to all wrapped rules | [] | - - ## assemble_targz diff --git a/WORKSPACE b/WORKSPACE index 913273c3..5f858cf8 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -17,7 +17,7 @@ # under the License. # -workspace(name="vaticle_bazel_distribution") +workspace(name="typedb_bazel_distribution") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") @@ -38,7 +38,7 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_reg kotlin_repositories() kt_register_toolchains() -load("@vaticle_bazel_distribution//maven:deps.bzl", "maven_artifacts_with_versions") +load("@typedb_bazel_distribution//maven:deps.bzl", "maven_artifacts_with_versions") load("@rules_jvm_external//:defs.bzl", "maven_install") maven_install( artifacts = maven_artifacts_with_versions, @@ -50,11 +50,17 @@ maven_install( fetch_sources = True, ) -# Load @vaticle_bazel_distribution_pip -load("//pip:deps.bzl", pip_deps = "deps") -pip_deps() -load("@vaticle_bazel_distribution_pip//:requirements.bzl", "install_deps") -install_deps() +# Load @typedb_bazel_distribution_pip +load("//pip:deps.bzl", "typedb_bazel_distribution_pip") +typedb_bazel_distribution_pip() +load("@typedb_bazel_distribution_pip//:requirements.bzl", pip_install_deps = "install_deps") +pip_install_deps() + +# Load //docs +load("//docs:python/deps.bzl", "typedb_bazel_distribution_docs_py") +typedb_bazel_distribution_docs_py() +load("@typedb_bazel_distribution_docs_py//:requirements.bzl", docs_py_install_deps = "install_deps") +docs_py_install_deps() # TODO: remove this declaration once we upgrade to @io_bazel_stardoc with Bazel 5 support # Load @bazel_skylib @@ -89,3 +95,9 @@ http_archive( load("@bazel_stardoc//:setup.bzl", "stardoc_repositories") stardoc_repositories() + +# Load @typedb_bazel_distribution_uploader +load("//common/uploader:deps.bzl", "typedb_bazel_distribution_uploader") +typedb_bazel_distribution_uploader() +load("@typedb_bazel_distribution_uploader//:requirements.bzl", uploader_install_deps = "install_deps") +uploader_install_deps() diff --git a/apt/generate_depends_file.py b/apt/generate_depends_file.py index 1d232c1b..50dc14ef 100644 --- a/apt/generate_depends_file.py +++ b/apt/generate_depends_file.py @@ -28,8 +28,8 @@ parser = argparse.ArgumentParser() parser.add_argument('--output', required=True, help='Output file') parser.add_argument('--version_file', required=True, help='File containing version of package being built') -parser.add_argument('--workspace_refs', help='Optional file with workspace references') -parser.add_argument('--deps', nargs='+', required=True, help='Dependency declarations') +parser.add_argument('--workspace_refs', help='File with workspace references (optional)') +parser.add_argument('--deps', nargs='+', help='Dependency declarations (optional)') args = parser.parse_args() workspace_refs = { @@ -60,7 +60,7 @@ deps = [] -for dep in args.deps: +for dep in (args.deps or []): match = WORKSPACE_REF_PATTERN.match(dep) if match: workspace_ref = match.group('workspace_ref') diff --git a/apt/rules.bzl b/apt/rules.bzl index 3d16b62e..78601630 100644 --- a/apt/rules.bzl +++ b/apt/rules.bzl @@ -149,13 +149,15 @@ def assemble_apt(name, name = version_file ) args = [ - "$(location @vaticle_bazel_distribution//apt:generate_depends_file)", + "$(location @typedb_bazel_distribution//apt:generate_depends_file)", "--output", "$@", "--version_file", "$(location {})".format(version_file), - "--deps" ] - for dep in depends: - args.append('"{}"'.format(dep)) + if len(depends): + args.append("--deps") + for dep in depends: + args.append('"{}"'.format(dep)) + srcs = [version_file] if workspace_refs: @@ -170,7 +172,7 @@ def assemble_apt(name, srcs = srcs, outs = ["{}.depends".format(name)], cmd = " ".join(args), - tools = ["@vaticle_bazel_distribution//apt:generate_depends_file"] + tools = ["@typedb_bazel_distribution//apt:generate_depends_file"] ) pkg_deb( @@ -187,27 +189,26 @@ def assemble_apt(name, def _deploy_apt_impl(ctx): + _deploy_script = ctx.actions.declare_file(ctx.attr.deploy_script_name) + package_path = ctx.files.target[0].short_path ctx.actions.expand_template( template = ctx.file._deployment_script, - output = ctx.outputs.deployment_script, + output = _deploy_script, substitutions = { '{snapshot}' : ctx.attr.snapshot, - '{release}' : ctx.attr.release + '{release}' : ctx.attr.release, + '{package_path}' : package_path, + '{version}' : ctx.var.get('version', '0.0.0') }, is_executable = True ) - symlinks = { - 'package.deb': ctx.files.target[0], - } - - return DefaultInfo(executable = ctx.outputs.deployment_script, - runfiles = ctx.runfiles( - files=[ctx.files.target[0]], - symlinks = symlinks)) + deployment_lib_files = ctx.attr._deployment_wrapper_lib[DefaultInfo].default_runfiles.files.to_list() + return DefaultInfo(executable = _deploy_script, + runfiles = ctx.runfiles(files=[ctx.files.target[0]] + deployment_lib_files)) -deploy_apt = rule( +_deploy_apt = rule( attrs = { "target": attr.label( doc = 'assemble_apt label to deploy' @@ -220,13 +221,17 @@ deploy_apt = rule( mandatory = True, doc = 'Release repository to deploy apt artifact to' ), + "_deployment_wrapper_lib": attr.label( + default = "//common/uploader:uploader", + ), "_deployment_script": attr.label( allow_single_file = True, default = "//apt/templates:deploy.py" ), - }, - outputs = { - "deployment_script": "%{name}.sh", + "deploy_script_name": attr.string( + mandatory = True, + doc = 'Name of instantiated deployment script' + ), }, implementation = _deploy_apt_impl, executable = True, @@ -235,3 +240,22 @@ deploy_apt = rule( Select deployment to `snapshot` or `release` repository with `bazel run //:some-deploy-apt -- [snapshot|release] """ ) + +def deploy_apt(name, target, snapshot, release, **kwargs): + deploy_script_target_name = name + "__deploy" + deploy_script_name = deploy_script_target_name + "-deploy.py" + + _deploy_apt( + name = deploy_script_target_name, + target = target, + snapshot = snapshot, + release = release, + deploy_script_name = deploy_script_name, + **kwargs + ) + + native.py_binary( + name = name, + srcs = [deploy_script_target_name], + main = deploy_script_name, + ) diff --git a/apt/templates/deploy.py b/apt/templates/deploy.py index c8c2bf54..9bc6ce36 100644 --- a/apt/templates/deploy.py +++ b/apt/templates/deploy.py @@ -31,18 +31,25 @@ import tempfile from runpy import run_path +import sys, glob +# Prefer using the runfile dependency than system dependency +runfile_deps = [path for path in map(os.path.abspath, glob.glob('external/*/*'))] +sys.path = runfile_deps + sys.path + +from common.uploader.uploader import Uploader + parser = argparse.ArgumentParser() parser.add_argument('repo_type') args = parser.parse_args() repo_type_key = args.repo_type -apt_deployments = { +apt_repositories = { 'snapshot' : "{snapshot}", 'release' : "{release}" } -apt_registry = apt_deployments[repo_type_key] +repo_url = apt_repositories[repo_type_key] apt_username, apt_password = ( os.getenv('DEPLOY_APT_USERNAME'), @@ -61,19 +68,11 @@ '$DEPLOY_APT_PASSWORD env variable' ) -upload_status_code = subprocess.check_output([ - 'curl', - '--silent', - '--output', '/dev/stderr', - '--write-out', '%{http_code}', - '-u', '{}:{}'.format(apt_username, apt_password), - '-X', 'POST', - '-H', 'Content-Type: multipart/form-data', - '--data-binary', '@package.deb', - apt_registry -]).decode().strip() +package_path = "{package_path}" +# Cloudsmith has a bug where packages with the same filename can break downloads +uploaded_filename = package_path.rstrip(".deb") + "_{version}.deb" -if upload_status_code != '201': - raise Exception('upload failed, got HTTP status code {}'.format(upload_status_code)) +uploader = Uploader.create(apt_username, apt_password, repo_url) +uploader.apt(package_path, uploaded_filename=uploaded_filename) print('Deployment completed.') diff --git a/artifact/rules.bzl b/artifact/rules.bzl index 684acc1c..7736c41b 100644 --- a/artifact/rules.bzl +++ b/artifact/rules.bzl @@ -22,15 +22,18 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") def _deploy_artifact_impl(ctx): _deploy_script = ctx.actions.declare_file(ctx.attr.deploy_script_name) - version_file = ctx.actions.declare_file(ctx.attr.name + "__do_not_reference.version") - version = ctx.var.get('version', '0.0.0') - - ctx.actions.run_shell( - inputs = [], - outputs = [version_file], - command = "echo {} > {}".format(version, version_file.path), - ) - + if ctx.attr.version_file: + version_file = ctx.file.version_file + else: + version_file = ctx.actions.declare_file(ctx.attr.name + "__do_not_reference.version") + version = ctx.var.get('version', '0.0.0') + + ctx.actions.run_shell( + inputs = [], + outputs = [version_file], + command = "echo {} > {}".format(version, version_file.path), + ) + ctx.actions.expand_template( template = ctx.file._deploy_script_template, output = _deploy_script, @@ -51,11 +54,11 @@ def _deploy_artifact_impl(ctx): symlinks = { 'VERSION': version_file, } - + deployment_lib_files = ctx.attr._deployment_wrapper_lib[DefaultInfo].default_runfiles.files.to_list() return DefaultInfo( executable = _deploy_script, runfiles = ctx.runfiles( - files = files, + files = files + deployment_lib_files, symlinks = symlinks, ), ) @@ -84,6 +87,9 @@ _deploy_artifact = rule( doc = "The artifact filename, automatic from the target file if not specified", default = '', ), + "_deployment_wrapper_lib": attr.label( + default = "//common/uploader:uploader", + ), "_deploy_script_template": attr.label( allow_single_file = True, default = "//artifact/templates:deploy.py", @@ -165,7 +171,7 @@ def artifact_file(name, http_file( name = name, - urls = ["{}/{}/{}/{}".format(repository_url, group_name, version, artifact_name)], + urls = ["{}/names/{}/versions/{}/{}".format(repository_url.rstrip("/"), group_name, version, artifact_name)], downloaded_file_path = artifact_name, sha = sha, tags = tags + ["{}={}".format(versiontype, version)], diff --git a/artifact/templates/deploy.py b/artifact/templates/deploy.py index 5219b3fa..51501634 100644 --- a/artifact/templates/deploy.py +++ b/artifact/templates/deploy.py @@ -27,20 +27,12 @@ import sys from posixpath import join as urljoin +import glob +# Prefer using the runfile dependency than system dependency +runfile_deps = [path for path in map(os.path.abspath, glob.glob('external/*/*'))] +sys.path = runfile_deps + sys.path -def upload(url, username, password, local_fn, remote_fn): - upload_status_code = sp.check_output([ - 'curl', '--silent', - '--write-out', '%{http_code}', - '-u', '{}:{}'.format(username, password), - '--upload-file', local_fn, - urljoin(url, remote_fn) - ]).decode().strip() - - if upload_status_code != '201': - raise Exception('upload of {} failed, got HTTP status code {}'.format( - local_fn, upload_status_code)) - +from common.uploader.uploader import Uploader if len(sys.argv) != 2: raise ValueError('Should pass only as arguments') @@ -58,7 +50,7 @@ def upload(url, username, password, local_fn, remote_fn): version = open("{version_file}", "r").read().strip() snapshot = 'snapshot' -version_snapshot_regex = '^[0-9|a-f|A-F]{40}$' +version_snapshot_regex = '^.*[0-9a-fA-F]{40}$' release = 'release' version_release_regex = '^[0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+)*$' @@ -75,9 +67,6 @@ def upload(url, username, password, local_fn, remote_fn): .format(version, repo_type, version_snapshot_regex)) filename = '{artifact_filename}' -if filename == '': - filename = os.path.basename('{artifact_path}') - filename = filename.format(version = version) base_url = None @@ -86,6 +75,5 @@ def upload(url, username, password, local_fn, remote_fn): else: base_url = '{snapshot}' -dir_url = '{base_url}/{artifact_group}/{version}'.format(version=version, base_url=base_url) - -upload(dir_url, username, password, '{artifact_path}', filename) +uploader = Uploader.create(username, password, base_url) +uploader.artifact("{artifact_group}", version, '{artifact_path}', filename) diff --git a/aws/rules.bzl b/aws/rules.bzl index bf087309..d4cbf882 100644 --- a/aws/rules.bzl +++ b/aws/rules.bzl @@ -38,7 +38,7 @@ def assemble_aws(name, generated_config_target_name = name + "__do_not_reference_config" generate_json_config( name = generated_config_target_name, - template = "@vaticle_bazel_distribution//aws:packer.template.json", + template = "@typedb_bazel_distribution//aws:packer.template.json", substitutions = { "{ami_name}": ami_name, "{install}": install_fn, diff --git a/azure/rules.bzl b/azure/rules.bzl index 1d5971a6..c15eadd7 100644 --- a/azure/rules.bzl +++ b/azure/rules.bzl @@ -48,7 +48,7 @@ def assemble_azure(name, generated_config_target_name = name + "__do_not_reference_config" generate_json_config( name = generated_config_target_name, - template = "@vaticle_bazel_distribution//azure:packer.template.json", + template = "@typedb_bazel_distribution//azure:packer.template.json", substitutions = { "{image_name}": image_name, "{resource_group_name}": resource_group_name, diff --git a/brew/templates/deploy.py b/brew/templates/deploy.py index 98e41d4e..fe83111e 100644 --- a/brew/templates/deploy.py +++ b/brew/templates/deploy.py @@ -27,6 +27,7 @@ import subprocess as sp import sys import tempfile +from typing import Dict import zipfile @@ -65,7 +66,7 @@ def verify_environment(): sys.exit(1) -def expand_formula_template(formula_template: str, substitution_files: dict[str, str]) -> str: +def expand_formula_template(formula_template: str, substitution_files: Dict[str, str]) -> str: expanded = formula_template for key, filename in substitution_files.items(): if os.path.isfile(filename): diff --git a/common/Logging.kt b/common/Logging.kt index 09c8b67d..00087337 100644 --- a/common/Logging.kt +++ b/common/Logging.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.common +package com.typedb.bazel.distribution.common object Logging { class Logger(private val logLevel: LogLevel) { diff --git a/common/Property.kt b/common/Property.kt index 7c3216ff..b0c2a43c 100644 --- a/common/Property.kt +++ b/common/Property.kt @@ -1,4 +1,4 @@ -package com.vaticle.bazel.distribution.common +package com.typedb.bazel.distribution.common enum class OS(private val displayName: String) { WINDOWS("Windows"), diff --git a/common/assemble_versioned/BUILD b/common/assemble_versioned/BUILD index 85154e54..a47fe199 100644 --- a/common/assemble_versioned/BUILD +++ b/common/assemble_versioned/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/checksum/BUILD b/common/checksum/BUILD index 7b1ac8a8..1df15aaf 100644 --- a/common/checksum/BUILD +++ b/common/checksum/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/deps.bzl b/common/deps.bzl index bf40089e..9235df11 100644 --- a/common/deps.bzl +++ b/common/deps.bzl @@ -5,7 +5,7 @@ def rules_python(): git_repository( name = "rules_python", remote = "https://github.com/bazelbuild/rules_python.git", - tag = "0.24.0", + tag = "0.31.0", ) def rules_pkg(): @@ -18,7 +18,7 @@ def rules_pkg(): def rules_kotlin(): http_archive( name = "io_bazel_rules_kotlin", - urls = ["https://github.com/vaticle/rules_kotlin/archive/c2519b00299cff9df22267e8359784e9948dba67.zip"], + urls = ["https://github.com/typedb/rules_kotlin/archive/c2519b00299cff9df22267e8359784e9948dba67.zip"], type = "zip", strip_prefix = "rules_kotlin-c2519b00299cff9df22267e8359784e9948dba67", sha256 = "1455f2ec4bf7ea12d2c90b0dfd6402553c3bb6cbc0271023e2e01ccdefb4a49a", diff --git a/common/generate_json_config/BUILD b/common/generate_json_config/BUILD index 7b1ac8a8..1df15aaf 100644 --- a/common/generate_json_config/BUILD +++ b/common/generate_json_config/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/java_deps/BUILD b/common/java_deps/BUILD index a2d595e8..63758ccb 100644 --- a/common/java_deps/BUILD +++ b/common/java_deps/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/rename/BUILD b/common/rename/BUILD index 7b1ac8a8..1df15aaf 100644 --- a/common/rename/BUILD +++ b/common/rename/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/rules.bzl b/common/rules.bzl index d24e58c8..becb74cb 100644 --- a/common/rules.bzl +++ b/common/rules.bzl @@ -17,15 +17,15 @@ # under the License. # -load("@vaticle_bazel_distribution//common/assemble_versioned:rules.bzl", _assemble_versioned = "assemble_versioned") -load("@vaticle_bazel_distribution//common/checksum:rules.bzl", _checksum = "checksum") -load("@vaticle_bazel_distribution//common/generate_json_config:rules.bzl", _generate_json_config = "generate_json_config") -load("@vaticle_bazel_distribution//common/java_deps:rules.bzl", _java_deps = "java_deps") -load("@vaticle_bazel_distribution//common/tgz2zip:rules.bzl", _tgz2zip = "tgz2zip") -load("@vaticle_bazel_distribution//common/targz:rules.bzl", _assemble_targz = "assemble_targz") -load("@vaticle_bazel_distribution//common/workspace_refs:rules.bzl", _workspace_refs = "workspace_refs") -load("@vaticle_bazel_distribution//common/zip:rules.bzl", _assemble_zip = "assemble_zip") -load("@vaticle_bazel_distribution//common/rename:rules.bzl", _file_rename = "file_rename") +load("@typedb_bazel_distribution//common/assemble_versioned:rules.bzl", _assemble_versioned = "assemble_versioned") +load("@typedb_bazel_distribution//common/checksum:rules.bzl", _checksum = "checksum") +load("@typedb_bazel_distribution//common/generate_json_config:rules.bzl", _generate_json_config = "generate_json_config") +load("@typedb_bazel_distribution//common/java_deps:rules.bzl", _java_deps = "java_deps") +load("@typedb_bazel_distribution//common/tgz2zip:rules.bzl", _tgz2zip = "tgz2zip") +load("@typedb_bazel_distribution//common/targz:rules.bzl", _assemble_targz = "assemble_targz") +load("@typedb_bazel_distribution//common/workspace_refs:rules.bzl", _workspace_refs = "workspace_refs") +load("@typedb_bazel_distribution//common/zip:rules.bzl", _assemble_zip = "assemble_zip", _unzip_file = "unzip_file") +load("@typedb_bazel_distribution//common/rename:rules.bzl", _file_rename = "file_rename") assemble_targz = _assemble_targz assemble_versioned = _assemble_versioned @@ -35,4 +35,5 @@ file_rename = _file_rename generate_json_config = _generate_json_config java_deps = _java_deps tgz2zip = _tgz2zip +unzip_file = _unzip_file workspace_refs = _workspace_refs diff --git a/common/shell/BUILD b/common/shell/BUILD index 09092110..4702e441 100644 --- a/common/shell/BUILD +++ b/common/shell/BUILD @@ -23,7 +23,7 @@ kt_jvm_library( name = "shell", srcs = glob(["*.kt"]), deps = [ - "@vaticle_bazel_distribution//common", + "@typedb_bazel_distribution//common", "@maven//:org_zeroturnaround_zt_exec", ], diff --git a/common/shell/Shell.kt b/common/shell/Shell.kt index 026a4317..b0f2e117 100644 --- a/common/shell/Shell.kt +++ b/common/shell/Shell.kt @@ -1,7 +1,7 @@ -package com.vaticle.bazel.distribution.common.shell +package com.typedb.bazel.distribution.common.shell -import com.vaticle.bazel.distribution.common.shell.Shell.Command.Companion.arg -import com.vaticle.bazel.distribution.common.Logging.Logger +import com.typedb.bazel.distribution.common.shell.Shell.Command.Companion.arg +import com.typedb.bazel.distribution.common.Logging.Logger import org.zeroturnaround.exec.ProcessExecutor import org.zeroturnaround.exec.ProcessResult import java.nio.file.Path @@ -38,8 +38,8 @@ class Shell(private val logger: Logger, private val verbose: Boolean = false, pr return verbose && (!sensitive || printSensitiveData) } - class Command(vararg args: Argument) { - val args = args.toList() + class Command(val args: List) { + constructor(vararg args: Argument): this(args.toList()) override fun toString(): String { return args.toString() diff --git a/common/targz/BUILD b/common/targz/BUILD index 7b1ac8a8..1df15aaf 100644 --- a/common/targz/BUILD +++ b/common/targz/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/targz/rules.bzl b/common/targz/rules.bzl index 1122e477..b851572e 100644 --- a/common/targz/rules.bzl +++ b/common/targz/rules.bzl @@ -18,7 +18,7 @@ # load("@rules_pkg//:pkg.bzl", "pkg_tar") -load("@vaticle_bazel_distribution//common/java_deps:rules.bzl", "java_deps") +load("@typedb_bazel_distribution//common/java_deps:rules.bzl", "java_deps") def _assemble_targz_package_dir_file_impl(ctx): version = ctx.var.get('version', '') @@ -96,8 +96,27 @@ def assemble_targz(name, tags = tags, ) -def targz_edit(name, src, strip_components = 0, **kwargs): - extra_args = ["--strip-components", str(strip_components)] +def targz_edit(name, src, strip_components = 0, exclude_globs = [], **kwargs): + """Edit distribution archive (.tar.gz) + + Args: + name: A unique name for this target, serves as the output filename. + src: The .tar.gz archive to edit. + strip_components (int): argument to tar -xz --strip-components + Remove the specified number of leading path elements. Pathnames + with fewer elements will be silently skipped. Note that the + pathname is edited after checking inclusion/exclusion patterns but + before security checks. + exclude_globs (list of strs): arguments to tar -xz --exclude + Do not process files or directories that match the specified pattern. + """ + extra_args = [] + if strip_components > 0: + extra_args.extend(["--strip-components", str(strip_components)]) + if exclude_globs: + for exclude_pattern in exclude_globs: + extra_args.extend(["--exclude", exclude_pattern]) + native.genrule( name = name, outs = [name], diff --git a/common/tgz2zip/BUILD b/common/tgz2zip/BUILD index 3d78d35b..0978666e 100644 --- a/common/tgz2zip/BUILD +++ b/common/tgz2zip/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/rpm/BUILD b/common/uploader/BUILD similarity index 66% rename from rpm/BUILD rename to common/uploader/BUILD index 7a6e8a06..0b867236 100644 --- a/rpm/BUILD +++ b/common/uploader/BUILD @@ -16,23 +16,11 @@ # specific language governing permissions and limitations # under the License. # +load("@typedb_bazel_distribution_uploader//:requirements.bzl", cloudsmith_requirement = "requirement") -load("@bazel_skylib//:bzl_library.bzl", "bzl_library") - -bzl_library( - name = "lib", - srcs = [ - "rules.bzl", - "@rules_pkg//:rpm.bzl", - ], - deps = [ - "@rules_pkg//doc_build:rules_pkg_lib", - ], - visibility = ["//visibility:public"] -) - -py_binary( - name = "generate_spec_file", - srcs = ["generate_spec_file.py"], - visibility = ["//visibility:public"] +py_library( + name = "uploader", + srcs = glob(["*.py"]), + deps = [cloudsmith_requirement("requests")], + visibility = ["//visibility:public"], ) diff --git a/common/uploader/__init__.py b/common/uploader/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/common/uploader/cloudsmith.py b/common/uploader/cloudsmith.py new file mode 100644 index 00000000..b199d6bf --- /dev/null +++ b/common/uploader/cloudsmith.py @@ -0,0 +1,159 @@ +import os +import re +import requests +import time +from .uploader import Uploader, DeploymentException + +class CloudsmithUploader(Uploader): + COMMON_OPTS = {"tags"} + _WAIT_FOR_SYNC_ATTEMPTS = 100 + _WAIT_FOR_SYNC_SLEEP_SEC = 3 + + # Interface with the cloudsmith api + def __init__(self, username, password, cloudsmith_url): + self.auth = requests.auth.HTTPBasicAuth(username, password) + res = re.search(r"cloudsmith:\/\/([^\/]+)/([^\/]+)\/?", cloudsmith_url) + if res is None: + raise DeploymentException( + "Invalid cloudsmith_url. Expected cloudsmith:/// but was: %s" % cloudsmith_url) + self.repo_owner = res.group(1) + self.repo = res.group(2) + + def _upload_file_impl(self, file, filename): + headers = {} + url = "https://upload.cloudsmith.io/%s/%s/%s" % (self.repo_owner, self.repo, filename) + return requests.put(url, auth=self.auth, headers=headers, data=open(file, 'rb').read()) + + def _post_metadata_impl(self, package_type, data): + headers = {} + url = "https://api-prd.cloudsmith.io/v1/packages/%s/%s/upload/%s/" % (self.repo_owner, self.repo, package_type) + return requests.post(url, auth=self.auth, headers=headers, json=data) + + def _wait_for_sync_impl(self, slug): + url = "https://api.cloudsmith.io/v1/packages/%s/%s/%s/status/" % (self.repo_owner, self.repo, slug) + syncing = True + response = None + ctr = 0 + while syncing: + if ctr >= CloudsmithUploader._WAIT_FOR_SYNC_ATTEMPTS: + raise DeploymentException("Sync still in progress after %d attempts. Failing..." % CloudsmithUploader._WAIT_FOR_SYNC_ATTEMPTS) + response = requests.get(url, auth=self.auth) + self._check_status_code("sync status", response) + json = response.json() + syncing = json["is_sync_in_progress"] or not (json["is_sync_completed"] or json["is_sync_failed"]) + ctr += 1 + time.sleep(CloudsmithUploader._WAIT_FOR_SYNC_SLEEP_SEC) + return response + + def _upload_file(self, file, filename): + print("Uploading file: %s" % filename) + resp = self._upload_file_impl(file, filename) + self._check_status_code("file upload", resp) + print("- Success!") + return resp.json()["identifier"] + + def _post_metadata(self, package_type, data): + print("Creating package: %s" % package_type) + resp = self._post_metadata_impl(package_type, data) + self._check_status_code("metadata post", resp) + print("- Success!") + return self._get_slug(resp) + + def _wait_for_sync(self, slug): + print("Checking sync status for slug: %s" % slug) + resp = self._wait_for_sync_impl(slug) + self._check_status_code("sync status", resp) + success = resp.json()["is_sync_completed"] + if success: + print("- Success!") + else: + raise DeploymentException("Syncing failed", resp) + return success + + def _check_status_code(self, stage, response): + if (response.status_code // 100) != 2: + raise DeploymentException("HTTP request for %s failed" % stage, response) + else: + return True + + def _validate_opts(self, opts, accepted_opts): + unrecognised_fields = [f for f in opts if f not in accepted_opts.union(CloudsmithUploader.COMMON_OPTS)] + if len(unrecognised_fields) != 0: + raise ValueError("Unrecognised option: " + str(unrecognised_fields)) + + def _get_slug(self, metadata_post_response): + return metadata_post_response.json()["slug_perm"] + + def _pick_filename(self, path, preferred_filename): + return preferred_filename if preferred_filename else os.path.basename(path) + + # Specific + def apt(self, deb_file, distro="any-distro/any-version", uploaded_filename = None, opts={}): + accepted_opts = set() + self._validate_opts(opts, accepted_opts) + # The uploaded filename is irrelevant. Cloudsmith sync will take care of it. + uploaded_filename = os.path.basename(deb_file) if uploaded_filename is None else uploaded_filename + uploaded_id = self._upload_file(deb_file, uploaded_filename) + data = { + "package_file": uploaded_id, + "distribution": distro, + } + slug = self._post_metadata("deb", data) + sync_success = self._wait_for_sync(slug) + assert (sync_success) + return sync_success, slug + + def artifact(self, artifact_group, version, artifact_path, filename, opts={}): + accepted_opts = {"description", "summary"} + self._validate_opts(opts, accepted_opts) + uploaded_id = self._upload_file(artifact_path, filename) + data = { + "package_file": uploaded_id, + "name": artifact_group, + "version": version + } + slug = self._post_metadata("raw", data) + sync_success = self._wait_for_sync(slug) + assert (sync_success) + return sync_success, slug + + def helm(self, tar_path, opts={}): + accepted_opts = set() + self._validate_opts(opts, accepted_opts) + uploaded_id = self._upload_file(tar_path, os.path.basename(tar_path)) + data = { + "package_file": uploaded_id, + } + slug = self._post_metadata("helm", data) + sync_success = self._wait_for_sync(slug) + assert (sync_success) + return sync_success, slug + + def maven(self, group_id, artifact_id, version, + jar_path, pom_path, + sources_path=None, javadoc_path=None, tests_path = None, + should_sign = True, + opts={}): + accepted_opts = {} + jar_filename, pom_filename, sources_filename, javadoc_filename, tests_filename = \ + Uploader._maven_names(artifact_id, version, sources_path, javadoc_path, tests_path) + self._validate_opts(opts, accepted_opts) + jar_id = self._upload_file(jar_path, self._pick_filename(jar_path, jar_filename)) + pom_id = self._upload_file(pom_path, self._pick_filename(pom_path, pom_filename)) + data = { + "group_id": group_id, + "artifact_id": artifact_id, + "package_file": jar_id, + "pom_file": pom_id + } + if sources_path is not None: + data["sources_file"] = self._upload_file(sources_path, self._pick_filename(sources_path, sources_filename)) + if javadoc_path is not None: + data["javadoc_file"] = self._upload_file(javadoc_path, self._pick_filename(javadoc_path, javadoc_filename)) + if tests_path is not None: + data["tests_file"] = self._upload_file(tests_path, self._pick_filename(tests_path, tests_filename)) + + slug = self._post_metadata("maven", data) + sync_success = self._wait_for_sync(slug) + assert (sync_success) + return sync_success, slug diff --git a/common/uploader/deps.bzl b/common/uploader/deps.bzl new file mode 100644 index 00000000..f54ab5a5 --- /dev/null +++ b/common/uploader/deps.bzl @@ -0,0 +1,10 @@ +load("@rules_python//python:pip.bzl", "pip_parse") + +def typedb_bazel_distribution_uploader(python_interpreter_target = None): + # Optionally specify the python interpreter to use instead of + # e.g. @_host//:python + pip_parse( + name = "typedb_bazel_distribution_uploader", + requirements_lock = "@typedb_bazel_distribution//common/uploader:requirements.txt", + python_interpreter_target = python_interpreter_target + ) diff --git a/common/uploader/nexus.py b/common/uploader/nexus.py new file mode 100644 index 00000000..c8a28ca5 --- /dev/null +++ b/common/uploader/nexus.py @@ -0,0 +1,133 @@ +import hashlib +import os +import requests + +from .uploader import Uploader, DeploymentException + +class NexusUploader(Uploader): + COMMON_OPTS = set() + + def __init__(self, username, password, url): + self.auth = requests.auth.HTTPBasicAuth(username, password) + + if not url.startswith("http"): + raise ValueError( + "Invalid url for repository. Expected http or https. Received:" % url) + self.repo_url = url.rstrip("/") + "/" + + def _upload_file_impl(self, file, url, use_post): + if use_post: + headers = {"Content-Type" : "multipart/form-data"} + return requests.post(url, auth = self.auth, data = open(file, "rb").read() , headers = headers) + else: + return requests.put(url, auth = self.auth, data = open(file, "rb").read()) + + def _upload_string_impl(self, data, url): + return requests.put(url, auth = self.auth, data = data) + + def _upload_file(self, file, url, use_post = False): + # self._upload_file_impl(file, url, use_post) + response = self._upload_file_impl(file, url, use_post) + success = (response.status_code // 100) == 2 + if not success: + raise DeploymentException("HTTP request for %s failed" % "upload", response) # TODO: Fix type + else: + return True + + def _upload_file_and_may_sign(self, file, url, should_sign): + use_post = False + stage = "upload" + response = self._upload_file_impl(file, url, use_post) + success = (response.status_code // 100)== 2 + if success and should_sign: + stage = "sign" + response = self._upload_file_impl(self._sign(file), url + ".asc", use_post) + success = (response.status_code // 100)== 2 + if success: + stage = "md5" + md5 = hashlib.md5(open(file, 'rb').read()).hexdigest() + response = self._upload_string_impl(md5, url + ".md5") + success = (response.status_code // 100)== 2 + if success: + stage = "sha1" + sha1 = hashlib.sha1(open(file, 'rb').read()).hexdigest() + response = self._upload_string_impl(sha1, url + ".sha1") + success = (response.status_code // 100)== 2 + + if not success: + from .cloudsmith import DeploymentException + raise DeploymentException("HTTP request for %s failed" % stage, response) + else: + return True + + def _validate_opts(self, opts, accepted_opts): + unrecognised_fields = [f for f in opts if f not in accepted_opts.union(NexusUploader.COMMON_OPTS)] + if len(unrecognised_fields) != 0: + raise ValueError("Unrecognised option: " + str(unrecognised_fields)) + + def _sign(self, fn): + import tempfile + import subprocess as sp + # TODO(vmax): current limitation of this functionality + # is that gpg key should already be present in keyring + # and should not require passphrase + asc_file = tempfile.mktemp() + sp.check_call([ + 'gpg', + '--detach-sign', + '--armor', + '--output', + asc_file, + fn + ]) + return asc_file + + #Impl + def apt(self, deb_file, distro="ignored", opts={}): + accepted_opts = set() + self._validate_opts(opts, accepted_opts) + upload_url = self.repo_url + success = self._upload_file(deb_file, upload_url, use_post = True) + return success, upload_url + + def artifact(self, artifact_group, version, artifact_path, filename, opts={}): + accepted_opts = set() + self._validate_opts(opts, accepted_opts) + upload_url = "%s/%s/%s/%s" %(self.repo_url.rstrip("/"), artifact_group, version, filename) + success = self._upload_file(artifact_path, upload_url) + return success, upload_url + + def helm(self, tar_path, opts={}): + accepted_opts = set() + self._validate_opts(opts, accepted_opts) + upload_url = "%s/api/charts/%s"%(self.repo_url.rstrip("/"), os.path.basename(tar_path)) + success = self._upload_file(tar_path, upload_url, use_post=False) + return success, upload_url + + def maven(self, group_id, artifact_id, version, + jar_path, pom_path, + sources_path=None, javadoc_path=None, tests_path = None, + should_sign = True, + opts={}): + accepted_opts = set() + self._validate_opts(opts, accepted_opts) + jar_filename, pom_filename, sources_filename, javadoc_filename, tests_filename = \ + Uploader._maven_names(artifact_id, version, sources_path, javadoc_path, tests_path) + base_url = "{repo_url}/{coordinates}/{artifact}/{version}/".format( + repo_url = self.repo_url.rstrip("/"), coordinates=group_id.replace('.', '/'), version=version, artifact=artifact_id) + jar_url = base_url + jar_filename + pom_url = base_url + pom_filename + success = True + success = success and self._upload_file_and_may_sign(jar_path, jar_url, should_sign) + success = success and self._upload_file_and_may_sign(pom_path, pom_url, should_sign) + if javadoc_path is not None: + javadoc_url = base_url + javadoc_filename + success = success and self._upload_file_and_may_sign(javadoc_path, javadoc_url, should_sign) + if sources_path is not None: + sources_url = base_url + sources_filename + success = success and self._upload_file_and_may_sign(sources_path, sources_url, should_sign) + if tests_path is not None: + tests_url = base_url + tests_filename + success = success and self._upload_file_and_may_sign(tests_path, tests_url, should_sign) + + return success, pom_url diff --git a/common/uploader/requirements.txt b/common/uploader/requirements.txt new file mode 100644 index 00000000..88648bd8 --- /dev/null +++ b/common/uploader/requirements.txt @@ -0,0 +1,5 @@ +requests==2.28.2 +certifi==2022.12.7 +charset-normalizer==3.0.1 +idna==3.4 +urllib3==1.26.14 diff --git a/common/uploader/uploader.py b/common/uploader/uploader.py new file mode 100644 index 00000000..169463ea --- /dev/null +++ b/common/uploader/uploader.py @@ -0,0 +1,56 @@ +import os +from abc import ABC,abstractmethod + +class DeploymentException(Exception): + def __init__(self, msg, response=None): + self.msg = msg + self.response = response + + def __str__(self): + ret = "DeploymentException: %s" % (self.msg) + if self.response is not None: + ret += ". HTTP response was [%d]: %s" % (self.response.status_code, self.response.text) + return ret + +class Uploader(ABC): + @staticmethod + def create(username, password, repo_url): + if repo_url.startswith("cloudsmith"): + from .cloudsmith import CloudsmithUploader + return CloudsmithUploader(username, password, repo_url) + elif repo_url.startswith("http"): + from .nexus import NexusUploader + return NexusUploader(username, password, repo_url) + else: + raise ValueError("Unrecognised url: ", repo_url) + + @staticmethod + def _maven_names(artifact_id, version, sources_path, javadoc_path, tests_path): + filename_base = '{artifact}-{version}'.format(artifact=artifact_id, version=version) + jar_filename = filename_base + ".jar" + pom_filename = filename_base + ".pom" + sources_filename = filename_base + "-sources.jar" if sources_path and os.path.exists(sources_path) else None + javadoc_filename = filename_base + "-javadoc.jar" if javadoc_path and os.path.exists(javadoc_path) else None + tests_path = filename_base + "-tests.jar" if tests_path and os.path.exists(tests_path) else None + return jar_filename, pom_filename, sources_filename, javadoc_filename, tests_path + + # Specific + @abstractmethod + def apt(self, deb_file, distro, opts={}): + raise NotImplementedError("Abstract") + + @abstractmethod + def artifact(self, artifact_group, version, artifact_path, filename, opts={}): + raise NotImplementedError("Abstract") + + @abstractmethod + def helm(self, tar_path, opts={}): + raise NotImplementedError("Abstract") + + @abstractmethod + def maven(self, group_id, artifact_id, version, + jar_path, pom_path, + sources_path=None, javadoc_path=None, tests_path = None, + should_sign = True, + opts={}): + raise NotImplementedError("Abstract") diff --git a/common/util/BUILD b/common/util/BUILD index 2fe01341..d37300dc 100644 --- a/common/util/BUILD +++ b/common/util/BUILD @@ -23,7 +23,7 @@ kt_jvm_library( name = "util", srcs = glob(["*.kt"]), deps = [ - "@vaticle_bazel_distribution//common" + "@typedb_bazel_distribution//common" ], visibility = ["//visibility:public"], ) diff --git a/common/util/FileUtil.kt b/common/util/FileUtil.kt index 27aad810..0ef00223 100644 --- a/common/util/FileUtil.kt +++ b/common/util/FileUtil.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.common.util +package com.typedb.bazel.distribution.common.util import java.io.File diff --git a/common/util/PropertiesUtil.kt b/common/util/PropertiesUtil.kt index b0d788e0..3a72ad1c 100644 --- a/common/util/PropertiesUtil.kt +++ b/common/util/PropertiesUtil.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.common.util +package com.typedb.bazel.distribution.common.util import java.util.Properties diff --git a/common/util/SystemUtil.kt b/common/util/SystemUtil.kt index 4e35b4b6..fc36ecab 100644 --- a/common/util/SystemUtil.kt +++ b/common/util/SystemUtil.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,12 +17,12 @@ * under the License. */ -package com.vaticle.bazel.distribution.common.util +package com.typedb.bazel.distribution.common.util -import com.vaticle.bazel.distribution.common.OS -import com.vaticle.bazel.distribution.common.OS.LINUX -import com.vaticle.bazel.distribution.common.OS.MAC -import com.vaticle.bazel.distribution.common.OS.WINDOWS +import com.typedb.bazel.distribution.common.OS +import com.typedb.bazel.distribution.common.OS.LINUX +import com.typedb.bazel.distribution.common.OS.MAC +import com.typedb.bazel.distribution.common.OS.WINDOWS import java.util.Locale.ENGLISH object SystemUtil { diff --git a/common/workspace_refs/BUILD b/common/workspace_refs/BUILD index 7b1ac8a8..1df15aaf 100644 --- a/common/workspace_refs/BUILD +++ b/common/workspace_refs/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/zip/BUILD b/common/zip/BUILD index 7b1ac8a8..1df15aaf 100644 --- a/common/zip/BUILD +++ b/common/zip/BUILD @@ -1,7 +1,4 @@ # -# Copyright (C) 2022 Vaticle -# -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/common/zip/rules.bzl b/common/zip/rules.bzl index 399ab040..b0985932 100644 --- a/common/zip/rules.bzl +++ b/common/zip/rules.bzl @@ -1,7 +1,5 @@ # -# Copyright (C) 2022 Vaticle -# -# This program is free software: you can redistribute it and/or modify +# This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. @@ -15,8 +13,8 @@ # along with this program. If not, see . # -load("@vaticle_bazel_distribution//common/targz:rules.bzl", "assemble_targz") -load("@vaticle_bazel_distribution//common/tgz2zip:rules.bzl", "tgz2zip") +load("@typedb_bazel_distribution//common/targz:rules.bzl", "assemble_targz") +load("@typedb_bazel_distribution//common/tgz2zip:rules.bzl", "tgz2zip") def assemble_zip( name, @@ -60,3 +58,21 @@ def assemble_zip( visibility = visibility, tags = tags, ) + +def unzip_file(name, target, output, **kwargs): + """Unzip a single-file archive + + Args: + name: unique name for this target + target: single input .zip archive + output: name for the unzipped file + """ + native.genrule( + name = name, + srcs = [target], + outs = [output], + tools = ["@bazel_tools//tools/zip:zipper"], + cmd_bash = "mkdir -p $(@D)/tmp && $(location @bazel_tools//tools/zip:zipper) x $< -d $(@D)/tmp && mv $(@D)/tmp/* $@", + cmd_bat = "MD $(@D)\\tmp && $(location @bazel_tools//tools/zip:zipper) x $< -d $(@D)\\tmp && MOVE $(@D)\\tmp\\* $@", + **kwargs + ) diff --git a/crates/BUILD b/crates/BUILD index 1a5f8d5b..a18d235c 100644 --- a/crates/BUILD +++ b/crates/BUILD @@ -48,7 +48,7 @@ kt_jvm_library( java_binary( name = "crate-assembler", - main_class = "com.vaticle.bazeldistribution.crates.CrateAssemblerKt", + main_class = "com.typedb.bazel.distribution.crates.CrateAssemblerKt", visibility = ["//visibility:public"], runtime_deps = [ ":crate-assembler-lib", @@ -69,7 +69,7 @@ kt_jvm_library( java_binary( name = "crate-deployer", - main_class = "com.vaticle.bazeldistribution.crates.CrateDeployerKt", + main_class = "com.typedb.bazel.distribution.crates.CrateDeployerKt", visibility = ["//visibility:public"], runtime_deps = [ ":crate-deployer-lib", diff --git a/crates/CrateAssembler.kt b/crates/CrateAssembler.kt index 5a53dd8b..d925bb77 100644 --- a/crates/CrateAssembler.kt +++ b/crates/CrateAssembler.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazeldistribution.crates +package com.typedb.bazel.distribution.crates import com.eclipsesource.json.Json import com.eclipsesource.json.JsonArray @@ -164,14 +162,23 @@ class CrateAssembler : Callable { private fun externalDepVersion(dep: String, bazelDepWorkspace: Map, workspaceRefs: JsonObject): String { val workspace = bazelDepWorkspace.get(dep) val commitDep = workspaceRefs.get("commits").asObject().get(workspace) - if (commitDep != null) return commitDep.asString(); + if (commitDep != null) return commitToVersion(commitDep.asString()); val tagDep = workspaceRefs.get("tags").asObject().get(workspace) - if (tagDep != null) return tagDep.asString(); + if (tagDep != null) return tagToVersion(tagDep.asString()); throw IllegalStateException(); } + private fun commitToVersion(commit: String): String { + return "0.0.0-${commit}" + } + + private fun tagToVersion(tag: String): String { + if (tag.contains("rc")) return tag.replace(Regex("-?rc"), "-rc") + else return tag + } + private fun writeCrateArchive(config: UnmodifiableConfig) { - val prefix = "$name-${versionFile.readText()}" + val prefix = "$name-${versionFile.readText().trim()}" outputCrateFile.outputStream().use { fos -> BufferedOutputStream(fos).use { bos -> GZIPOutputStream(bos).use { gzos -> @@ -226,7 +233,7 @@ class CrateAssembler : Callable { cargoToml.set("package", this) set("name", name) set("edition", edition) - set("version", versionFile.readText()) + set("version", tagToVersion(versionFile.readText().trim())) set>("authors", authors.filter { it != "" }) set("homepage", homepage) set("repository", repository) diff --git a/crates/CrateDeployer.kt b/crates/CrateDeployer.kt index d3113418..9870595f 100644 --- a/crates/CrateDeployer.kt +++ b/crates/CrateDeployer.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazeldistribution.crates +package com.typedb.bazel.distribution.crates import com.eclipsesource.json.Json import com.google.api.client.http.* @@ -60,8 +58,8 @@ class CrateDeployer : Callable { private val repoUrl: String get() = when (releaseMode) { - CrateRepoType.Snapshot -> snapshotRepo - CrateRepoType.Release -> releaseRepo + CrateRepoType.Snapshot -> snapshotRepo.trim('/') + CrateRepoType.Release -> releaseRepo.trim('/') } + "/api/v1/crates/new" private val token = System.getenv("DEPLOY_CRATE_TOKEN") ?: throw RuntimeException( @@ -99,7 +97,7 @@ class CrateDeployer : Callable { private fun httpPut(url: String, token: String, content: ByteArray): HttpResponse { return NetHttpTransport() .createRequestFactory() - .buildPutRequest(GenericUrl(url), ByteArrayContent("application/json", content)) + .buildPutRequest(GenericUrl(url), ByteArrayContent(null, content)) // TODO: Verify it works with crates.io .setHeaders( HttpHeaders().setAuthorization(token) ) diff --git a/crates/rules.bzl b/crates/rules.bzl index d442f04b..973905c5 100644 --- a/crates/rules.bzl +++ b/crates/rules.bzl @@ -263,7 +263,7 @@ assemble_crate = rule( "_crate_assembler_tool": attr.label( executable = True, cfg = "host", - default = "@vaticle_bazel_distribution//crates:crate-assembler", + default = "@typedb_bazel_distribution//crates:crate-assembler", ), }, outputs = { @@ -317,11 +317,11 @@ deploy_crate = rule( ), "_crate_deployer": attr.label( allow_single_file = True, - default = "@vaticle_bazel_distribution//crates:crate-deployer_deploy.jar" + default = "@typedb_bazel_distribution//crates:crate-deployer_deploy.jar" ), "_crate_deployer_wrapper_template": attr.label( allow_single_file = True, - default = "@vaticle_bazel_distribution//crates/templates:deploy.sh", + default = "@typedb_bazel_distribution//crates/templates:deploy.sh", ) }, executable = True, diff --git a/doc_hub.bzl b/doc_hub.bzl index ff7adb99..58e07a8c 100644 --- a/doc_hub.bzl +++ b/doc_hub.bzl @@ -47,6 +47,9 @@ load("//common/tgz2zip:rules.bzl", _tgz2zip = "tgz2zip") load("//crates:rules.bzl", _assemble_crate = "assemble_crate", _deploy_crate = "deploy_crate") +load("//docs/doxygen:rules.bzl", _doxygen_docs = "doxygen_docs") +load("//docs/python:rules.bzl", _sphinx_docs = "sphinx_docs") + load("//gcp:rules.bzl", _assemble_gcp = "assemble_gcp") load('//github:rules.bzl', _deploy_github = "deploy_github") @@ -64,8 +67,6 @@ load("//packer:rules.bzl", _assemble_packer = "assemble_packer", _deploy_packer load("//pip:rules.bzl", _assemble_pip = "assemble_pip", _deploy_pip = "deploy_pip") -load("//rpm:rules.bzl", _assemble_rpm = "assemble_rpm", _deploy_rpm = "deploy_rpm") - assemble_apt = _assemble_apt deploy_apt = _deploy_apt @@ -94,6 +95,9 @@ tgz2zip = _tgz2zip assemble_crate = _assemble_crate deploy_crate = _deploy_crate +doxygen_docs = _doxygen_docs +sphinx_docs = _sphinx_docs + assemble_gcp = _assemble_gcp deploy_github = _deploy_github @@ -111,6 +115,3 @@ deploy_packer = _deploy_packer assemble_pip = _assemble_pip deploy_pip = _deploy_pip - -assemble_rpm = _assemble_rpm -deploy_rpm = _deploy_rpm diff --git a/docs/BUILD b/docs/BUILD new file mode 100644 index 00000000..e33cd742 --- /dev/null +++ b/docs/BUILD @@ -0,0 +1,43 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +exports_files(["doxygen/doxyfile.template"]) + +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@typedb_bazel_distribution_docs_py//:requirements.bzl", docs_requirement = "requirement") + +py_binary( + name = "sphinx_runner", + srcs = [ + "python/sphinx_html_builder.py", + ], + main = "sphinx_html_builder.py", + deps = [docs_requirement("sphinx")], + visibility = ["//visibility:public"] +) + +bzl_library( + name = "lib", + srcs = [ + "doxygen/rules.bzl", + "python/rules.bzl", + ], + deps = [], + visibility = ["//visibility:public"], +) diff --git a/docs/doxygen/doxyfile.template b/docs/doxygen/doxyfile.template new file mode 100644 index 00000000..883efd49 --- /dev/null +++ b/docs/doxygen/doxyfile.template @@ -0,0 +1,105 @@ +# Doxyfile 1.9.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +#--------------------------------------------------------------------------- +# NOTE: +# This file has been cleaned up for doxygen doc generation via bazel +# To see all the options, generate a fresh one with +# `doxygen -g ` + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = ##{{PROJECT_NAME}} +PROJECT_NUMBER = ##{{PROJECT_NUMBER}} +PROJECT_BRIEF = ##{{PROJECT_BRIEF}} +OUTPUT_DIRECTORY = ##{{OUTPUT_DIRECTORY}} +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English + +BRIEF_MEMBER_DESC = YES +ALWAYS_DETAILED_SEC = YES +REPEAT_BRIEF = YES +STRIP_FROM_PATH = ##{{STRIP_FROM_PATH}} +INHERIT_DOCS = YES +INLINE_INHERITED_MEMB = NO + +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +FILE_PATTERNS = *.h *.hpp *.md *.html +CASE_SENSE_NAMES = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +HIDE_FRIEND_COMPOUNDS = YES +SHOW_HEADERFILE = NO ## Show which header to include +SHOW_INCLUDE_FILES = NO +SORT_BRIEF_DOCS = NO ## NO: The short description at the top is in declaration order +SORT_MEMBER_DOCS = YES ## YES: The longer description which follows is sorted alphabetically +SORT_BY_SCOPE_NAME = NO + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES +WARN_NO_PARAMDOC = YES +WARN_IF_UNDOC_ENUM_VAL = YES +WARN_AS_ERROR = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ##{{INPUT}} +INPUT_ENCODING = UTF-8 +RECURSIVE = NO ## bazel explicitly specifies files +EXCLUDE_SYMLINKS = NO ## bazel needs NO +USE_MDFILE_AS_MAINPAGE = ##{{USE_MDFILE_AS_MAINPAGE}} +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_COLORSTYLE = AUTO_LIGHT +ENUM_VALUES_PER_LINE = 4 +OBFUSCATE_EMAILS = YES +SEARCHENGINE = YES + +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +# Configuration options related to diagram generator tools +#--------------------------------------------------------------------------- +HIDE_UNDOC_RELATIONS = YES +CLASS_GRAPH = YES +HAVE_DOT = NO ## Disables many details + +#--------------------------------------------------------------------------- +# Configuration options related to optional content included to the output +#--------------------------------------------------------------------------- +EXTRACT_STATIC = YES diff --git a/docs/doxygen/rules.bzl b/docs/doxygen/rules.bzl new file mode 100644 index 00000000..0fc364a9 --- /dev/null +++ b/docs/doxygen/rules.bzl @@ -0,0 +1,102 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +def _doxygen_docs_impl(ctx): + output_directory = ctx.actions.declare_directory(ctx.attr._output_directory) + files = [] + for target in ctx.attr.sources: + files.extend(target.files.to_list()) + + replacements = { + "PROJECT_NAME": '"' + ctx.attr.project_name + '"', + "PROJECT_NUMBER" : ctx.attr.version, + "PROJECT_BRIEF" : ctx.attr.desc, + "OUTPUT_DIRECTORY" : output_directory.path, + "STRIP_FROM_PATH": ctx.attr.strip_prefix, + } + if ctx.file.main_page_md != None: + files.append(ctx.file.main_page_md) + replacements["USE_MDFILE_AS_MAINPAGE"] = ctx.file.main_page_md.path + + replacements["INPUT"] = " ".join([f.path for f in files]) + + # Prepare doxyfile + doxyfile = ctx.actions.declare_file("%s.doxyfile" % ctx.attr.name) + ctx.actions.expand_template( + template = ctx.file._doxyfile_template, + output = doxyfile, + substitutions = {"##{{%s}}"%k : replacements[k] for k in replacements} + ) + + files = [doxyfile] + files + print(doxyfile.path) + ctx.actions.run( + inputs = files, + outputs = [output_directory], + arguments = [doxyfile.path], + executable = "doxygen", + use_default_shell_env = True + ) + + return DefaultInfo(files = depset([output_directory])) + +doxygen_docs = rule( + implementation = _doxygen_docs_impl, + test = False, + attrs = { + "project_name" : attr.string( + doc = "The project name for the doxygen docs", + mandatory = True, + ), + "version" : attr.string( + doc = "The version of the project being documented", + default = "" + ), + "desc" : attr.string( + doc = "A description for the project", + default = "" + ), + "sources" : attr.label_list( + doc = "A list of files made available to doxygen. This is NOT automatically included in the doxyfile", + mandatory = True, + allow_files = True, + ), + "strip_prefix" : attr.string( + doc = "Prefix to strip from path of files being processed", + default = "" + ), + "main_page_md" : attr.label( + doc = "The file to use as main page for the generate docs", + allow_single_file = True, + mandatory = False + ), + "_doxyfile_template" : attr.label( + allow_single_file = True, + default = "//docs:doxygen/doxyfile.template" + ), + "_output_directory" : attr.string( + doc = "The output directory for the doxygen docs", + default = "doxygen_docs" + ) + }, + doc = """ + Creates HTML documentation for C++ and C# projects using Doxygen. + This rule is not hermetic, and requires doxygen to be installed on the host. + """ +) diff --git a/docs/java/deps.bzl b/docs/java/deps.bzl new file mode 100644 index 00000000..62fefb4f --- /dev/null +++ b/docs/java/deps.bzl @@ -0,0 +1,25 @@ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +def google_bazel_common(): + # Bazel Common Libraries (with javadoc) + http_archive( + name = "google_bazel_common", + sha256 = "e982cc2e4c9a7d664e77d97a99debb3d18261e6ac6ea5bc4d8f453a521fdf1cf", + strip_prefix = "bazel-common-78cc73600ddfa62f953652625abd7c6f1656cfac", + urls = ["https://github.com/google/bazel-common/archive/78cc73600ddfa62f953652625abd7c6f1656cfac.zip"], + ) diff --git a/docs/python/deps.bzl b/docs/python/deps.bzl new file mode 100644 index 00000000..1f2516df --- /dev/null +++ b/docs/python/deps.bzl @@ -0,0 +1,22 @@ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +load("@rules_python//python:pip.bzl", "pip_parse") + +def typedb_bazel_distribution_docs_py(): + pip_parse( + name = "typedb_bazel_distribution_docs_py", + requirements_lock = "@typedb_bazel_distribution//docs:python/requirements.txt", + ) diff --git a/docs/python/requirements.txt b/docs/python/requirements.txt new file mode 100644 index 00000000..3c22e712 --- /dev/null +++ b/docs/python/requirements.txt @@ -0,0 +1,46 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +alabaster==0.7.13 +Babel==2.12.1 +certifi==2022.12.7 +charset-normalizer==3.1.0 +docutils==0.18.1 +idna==3.4 +imagesize==1.4.1 +importlib-metadata==6.1.0 +Jinja2==3.1.2 +MarkupSafe==2.1.2 +packaging==23.0 +Pygments==2.14.0 +pytz==2023.2 +requests==2.28.2 +snowballstemmer==2.2.0 +Sphinx==6.1.3 +sphinx-rtd-theme==1.2.0 +sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-jquery==4.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.5 +typing-extensions==4.5.0 +urllib3==1.26.15 +zipp==3.15.0 diff --git a/docs/python/rules.bzl b/docs/python/rules.bzl new file mode 100644 index 00000000..c50a08a5 --- /dev/null +++ b/docs/python/rules.bzl @@ -0,0 +1,82 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +def _sphinx_docs_impl(ctx): + package = ctx.actions.declare_directory("package") + + ctx.actions.run_shell( + inputs = ctx.files.target, + outputs = [package], + command = 'PACKAGE=$(find . -name "*.tar.gz") && tar -xf ${PACKAGE} && mv */%s %s' + % (ctx.attr.package_subdir, package.path), + ) + + args = ctx.actions.args() + args.add('--output', ctx.outputs.out.path) + args.add('--package', package.path) + args.add('--source_dir', ctx.files.sphinx_conf[0].dirname) + + ctx.actions.run( + inputs = [ctx.executable._script, package] + ctx.files.sphinx_conf + ctx.files.sphinx_rst, + outputs = [ctx.outputs.out], + arguments = [args], + executable = ctx.executable._script, + env = {"PYTHONPATH": package.path}, + ) + + return DefaultInfo(files = depset([ctx.outputs.out])) + + +sphinx_docs = rule( + attrs = { + "_script": attr.label( + default = ":sphinx_runner", + executable = True, + cfg = "exec", + doc = "Script for running sphinx", + ), + "target": attr.label( + mandatory = True, + allow_files = True, + doc = "Package including .tar.gz archive", + ), + "sphinx_conf": attr.label( + mandatory = True, + allow_files = True, + doc = "Configuration file for the Sphinx documentation builder", + ), + "sphinx_rst": attr.label( + mandatory = True, + allow_files = True, + doc = "Sphinx documentation master file for the package", + ), + "out": attr.output( + mandatory = True, + doc = "Output directory", + ), + "package_subdir": attr.string( + mandatory = True, + doc = "Directory with the module files in the package archive", + ) + }, + implementation = _sphinx_docs_impl, + doc = """ + Creates an HTML documentation for python module using Sphinx. + """ +) diff --git a/docs/python/sphinx_html_builder.py b/docs/python/sphinx_html_builder.py new file mode 100644 index 00000000..3eb9d2a2 --- /dev/null +++ b/docs/python/sphinx_html_builder.py @@ -0,0 +1,34 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +import argparse +import sys + +from sphinx.cmd.build import main +from sphinx.ext import apidoc + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--output', help="Output directory") + parser.add_argument('--package', help="Package directory") + parser.add_argument('--source_dir', help="Sphinx source directory") + args = parser.parse_args() + + apidoc.main(["-o", args.source_dir, args.package]) + sys.exit(main(["-M", "html", args.source_dir, args.output])) diff --git a/gcp/packer.template.json b/gcp/packer.template.json index 3e44e159..5cd598e4 100644 --- a/gcp/packer.template.json +++ b/gcp/packer.template.json @@ -14,7 +14,7 @@ "image_name": "{image_name}", "image_family": "{image_family}", "image_licenses": {image_licenses}, - "disk_size": 20, + "disk_size": 50, "disable_default_service_account": {disable_default_service_account} } ], diff --git a/gcp/rules.bzl b/gcp/rules.bzl index 1dda21c4..81a62ce8 100644 --- a/gcp/rules.bzl +++ b/gcp/rules.bzl @@ -51,7 +51,7 @@ def assemble_gcp(name, generated_config_target_name = name + "__do_not_reference_config" generate_json_config( name = generated_config_target_name, - template = "@vaticle_bazel_distribution//gcp:packer.template.json", + template = "@typedb_bazel_distribution//gcp:packer.template.json", substitutions = { "{project_id}": project_id, "{zone}": zone, diff --git a/github/deps.bzl b/github/deps.bzl index facf97ff..3b14ac33 100644 --- a/github/deps.bzl +++ b/github/deps.bzl @@ -19,7 +19,7 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -def deps(): +def ghr_osx_zip(): http_archive( name = "ghr_osx_zip", urls = ["https://github.com/tcnksm/ghr/releases/download/v0.12.1/ghr_v0.12.1_darwin_amd64.zip"], @@ -27,6 +27,8 @@ def deps(): strip_prefix = "ghr_v0.12.1_darwin_amd64", build_file_content = 'exports_files(["ghr"])' ) + +def ghr_linux_tar(): http_archive( name = "ghr_linux_tar", urls = ["https://github.com/tcnksm/ghr/releases/download/v0.12.1/ghr_v0.12.1_linux_amd64.tar.gz"], diff --git a/helm/BUILD b/helm/BUILD new file mode 100644 index 00000000..e69de29b diff --git a/helm/rules.bzl b/helm/rules.bzl new file mode 100644 index 00000000..ae5bb909 --- /dev/null +++ b/helm/rules.bzl @@ -0,0 +1,91 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") + +def _deploy_helm_impl(ctx): + _deploy_script = ctx.actions.declare_file(ctx.attr.deploy_script_name) + ctx.actions.expand_template( + template = ctx.file._deploy_script_template, + output = _deploy_script, + substitutions = { + "{chart_path}": ctx.file.chart.short_path, + "{release}": ctx.attr.release, + "{snapshot}": ctx.attr.snapshot, + }, + ) + + deployment_lib_files = ctx.attr._deployment_wrapper_lib[DefaultInfo].default_runfiles.files.to_list() + return DefaultInfo( + executable = _deploy_script, + runfiles = ctx.runfiles( + files = [ctx.file.chart] + deployment_lib_files + ), + ) + +_deploy_helm = rule( + attrs = { + "chart": attr.label( + allow_single_file = True, + mandatory = True, + doc = "Chart to deploy to repo", + ), + "_deployment_wrapper_lib": attr.label( + default = "//common/uploader:uploader", + ), + "_deploy_script_template": attr.label( + allow_single_file = True, + default = "//helm/templates:deploy.py", + ), + "deploy_script_name": attr.string( + mandatory = True, + doc = 'Name of instantiated deployment script' + ), + "release": attr.string( + mandatory = True, + doc = "Repository that the release chart will be uploaded to" + ), + "snapshot": attr.string( + mandatory = True, + doc = "Repository that the snapshot chart will be uploaded to" + ), + }, + executable = True, + implementation = _deploy_helm_impl, + doc = "Deploy helm chart into a raw repo", +) + +def deploy_helm(name, chart, snapshot, release, **kwargs): + deploy_script_target_name = name + "__deploy" + deploy_script_name = deploy_script_target_name + "-deploy.py" + + _deploy_helm( + name = deploy_script_target_name, + chart = chart, + deploy_script_name = deploy_script_name, + snapshot = snapshot, + release = release, + **kwargs + ) + + native.py_binary( + name = name, + srcs = [deploy_script_target_name], + main = deploy_script_name, + ) diff --git a/rpm/templates/BUILD b/helm/templates/BUILD similarity index 100% rename from rpm/templates/BUILD rename to helm/templates/BUILD diff --git a/helm/templates/deploy.py b/helm/templates/deploy.py new file mode 100644 index 00000000..3fe78817 --- /dev/null +++ b/helm/templates/deploy.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. +# + +from __future__ import print_function + +import os +import re +import subprocess as sp +import sys +from posixpath import join as urljoin + +import glob +# Prefer using the runfile dependency than system dependency +runfile_deps = [path for path in map(os.path.abspath, glob.glob('external/*/*'))] +sys.path = runfile_deps + sys.path + +from common.uploader.uploader import Uploader + +if len(sys.argv) != 2: + raise ValueError('Should pass only as arguments') + +_, repo_type = sys.argv + +username, password = os.getenv('DEPLOY_HELM_USERNAME'), os.getenv('DEPLOY_HELM_PASSWORD') + +if not username: + raise ValueError('Error: username should be passed via $DEPLOY_HELM_USERNAME env variable') + +if not password: + raise ValueError('Error: password should be passed via $DEPLOY_HELM_PASSWORD env variable') + +chart_path = '{chart_path}' +filename = os.path.basename('{chart_path}') + +snapshot = 'snapshot' +version_snapshot_regex = '.*-0.0.0-[0-9|a-f|A-F]{40}.*' +release = 'release' +version_release_regex = '.*-[0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+)*.*' + +if repo_type not in [snapshot, release]: + raise ValueError("Invalid repository type: {}. It should be one of these: {}" + .format(repo_type, [snapshot, release])) +if repo_type == 'snapshot' and len(re.findall(version_snapshot_regex, filename)) == 0: + raise ValueError('Invalid version: {}. A helm chart uploaded to a {} repository ' + 'must contain a version in its filename which complies to this regex: {}' + .format(filename, repo_type, version_snapshot_regex)) +if repo_type == 'release' and len(re.findall(version_release_regex, filename)) == 0: + raise ValueError('Invalid version: {}. An helm chart uploaded to a {} repository ' + 'must contain a version in its filename which complies to this regex: {}' + .format(filename, repo_type, version_snapshot_regex)) + +base_url = None +if repo_type == 'release': + base_url = '{release}' +else: + base_url = '{snapshot}' + +uploader = Uploader.create(username, password, base_url) +uploader.helm(chart_path) diff --git a/maven/BUILD b/maven/BUILD index 638833d9..b696c7bd 100644 --- a/maven/BUILD +++ b/maven/BUILD @@ -48,7 +48,7 @@ java_binary( runtime_deps = [ ":pom-generator-lib" ], - main_class = "com.vaticle.bazel.distribution.maven.PomGeneratorKt", + main_class = "com.typedb.bazel.distribution.maven.PomGeneratorKt", visibility = ["//visibility:public"] ) @@ -68,6 +68,6 @@ java_binary( runtime_deps = [ ":jar-assembler-lib" ], - main_class = "com.vaticle.bazel.distribution.maven.JarAssemblerKt", + main_class = "com.typedb.bazel.distribution.maven.JarAssemblerKt", visibility = ["//visibility:public"] ) diff --git a/maven/JarAssembler.kt b/maven/JarAssembler.kt index f2c29621..caeb204d 100644 --- a/maven/JarAssembler.kt +++ b/maven/JarAssembler.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.maven +package com.typedb.bazel.distribution.maven import picocli.CommandLine import picocli.CommandLine.Command diff --git a/maven/PomGenerator.kt b/maven/PomGenerator.kt index 0088ffd1..ad508744 100644 --- a/maven/PomGenerator.kt +++ b/maven/PomGenerator.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.maven +package com.typedb.bazel.distribution.maven import com.eclipsesource.json.Json import com.eclipsesource.json.JsonObject @@ -102,13 +100,9 @@ class PomGenerator : Callable { return version } val versionCommit = workspaceRefs.get("commits").asObject().get(originalVersion) - if (versionCommit != null) { - return versionCommit.asString() - } + if (versionCommit != null) return commitToVersion(versionCommit.asString()) val tagCommit = workspaceRefs.get("tags").asObject().get(originalVersion) - if (tagCommit != null) { - return tagCommit.asString() - } + if (tagCommit != null) return tagToVersion(tagCommit.asString()) return originalVersion } @@ -195,7 +189,7 @@ class PomGenerator : Callable { } override fun call() { - val version = versionFile.readText() + val version = tagToVersion(versionFile.readText().trim()) val workspaceRefs = Json.parse(workspaceRefsFile.readText()).asObject() // Create an XML document for constructing the POM @@ -258,6 +252,15 @@ class PomGenerator : Callable { // write the final result outputDocumentToFile(pom) } + + private fun commitToVersion(commit: String): String { + return "0.0.0-$commit" + } + + private fun tagToVersion(tag: String): String { + if (tag.contains("rc")) return tag.replace(Regex("-?rc"), "-rc") + else return tag + } } private operator fun JsonObject.Member.component1(): String = name diff --git a/maven/deps.bzl b/maven/deps.bzl index 4e8c39ea..0a32ddd5 100644 --- a/maven/deps.bzl +++ b/maven/deps.bzl @@ -23,6 +23,7 @@ maven_artifacts = [ "com.google.http-client:google-http-client", "info.picocli:picocli", "org.apache.commons:commons-compress", + "org.jsoup:jsoup", "org.zeroturnaround:zt-exec", ] @@ -33,5 +34,6 @@ maven_artifacts_with_versions = [ "com.google.http-client:google-http-client:1.34.2", "info.picocli:picocli:4.3.2", "org.apache.commons:commons-compress:1.21", + "org.jsoup:jsoup:1.16.1", "org.zeroturnaround:zt-exec:1.10", ] diff --git a/maven/rules.bzl b/maven/rules.bzl index 3e746b92..12092493 100644 --- a/maven/rules.bzl +++ b/maven/rules.bzl @@ -38,6 +38,10 @@ def _generate_version_file(ctx): version_file = ctx.actions.declare_file(ctx.attr.name + "__do_not_reference.version") version = ctx.var.get("version", "0.0.0") + if len(version) == 40: + # this is a commit SHA, most likely + version = "0.0.0-{}".format(version) + ctx.actions.run_shell( inputs = [], outputs = [version_file], @@ -315,12 +319,12 @@ assemble_maven( """, ), "_pom_generator": attr.label( - default = "@vaticle_bazel_distribution//maven:pom-generator", + default = "@typedb_bazel_distribution//maven:pom-generator", executable = True, cfg = "host", ), "_jar_assembler": attr.label( - default = "@vaticle_bazel_distribution//maven:jar-assembler", + default = "@typedb_bazel_distribution//maven:jar-assembler", executable = True, cfg = "host", ), @@ -374,9 +378,10 @@ def _deploy_maven_impl(ctx): files.append(ctx.attr.target[MavenDeploymentInfo].srcjar) symlinks[src_jar_link] = ctx.attr.target[MavenDeploymentInfo].srcjar + deployment_lib_files = ctx.attr._deployment_wrapper_lib[DefaultInfo].default_runfiles.files.to_list() return DefaultInfo( executable = deploy_maven_script, - runfiles = ctx.runfiles(files=files, symlinks = symlinks) + runfiles = ctx.runfiles(files=files + deployment_lib_files, symlinks = symlinks) ) _deploy_maven = rule( @@ -394,6 +399,9 @@ _deploy_maven = rule( mandatory = True, doc = 'Release repository to release maven artifact to' ), + "_deployment_wrapper_lib": attr.label( + default = "//common/uploader:uploader", + ), "_deploy_script_template": attr.label( allow_single_file = True, default = "//maven/templates:deploy.py", diff --git a/maven/templates/deploy.py b/maven/templates/deploy.py index b194ee3b..b13a1ac0 100644 --- a/maven/templates/deploy.py +++ b/maven/templates/deploy.py @@ -30,57 +30,13 @@ import tempfile from posixpath import join as urljoin +import sys, glob -def sha1(fn): - return hashlib.sha1(open(fn, 'rb').read()).hexdigest() +# Prefer using the runfile dependency than system dependency +runfile_deps = [path for path in map(os.path.abspath, glob.glob('external/*/*'))] +sys.path = runfile_deps + sys.path - -def md5(fn): - return hashlib.md5(open(fn, 'rb').read()).hexdigest() - - -def upload_file(url, username, password, local_fn, remote_fn): - upload_status_code = sp.check_output([ - 'curl', '--silent', - '--write-out', '%{http_code}', - '-u', '{}:{}'.format(username, password), - '--upload-file', local_fn, - urljoin(url, remote_fn) - ]).decode().strip() - - if upload_status_code not in {'200', '201'}: - raise Exception('upload_file of {} failed, got HTTP status code {}'.format( - local_fn, upload_status_code)) - - -def upload_str(url, username, password, string, remote_fn): - upload_status_code = sp.check_output([ - 'curl', '--silent', - '--write-out', '%{http_code}', - '-u', '{}:{}'.format(username, password), - '--upload-file', '-', - urljoin(url, remote_fn) - ], input=string.encode()).decode().strip() - - if upload_status_code not in {'200', '201'}: - raise Exception('upload_str of "{}" failed, got HTTP status code {}'.format( - string, upload_status_code)) - - -def sign(fn): - # TODO(vmax): current limitation of this functionality - # is that gpg key should already be present in keyring - # and should not require passphrase - asc_file = tempfile.mktemp() - sp.check_call([ - 'gpg', - '--detach-sign', - '--armor', - '--output', - asc_file, - fn - ]) - return asc_file +from common.uploader.uploader import Uploader def unpack_args(_, a, b=False): @@ -90,9 +46,10 @@ def unpack_args(_, a, b=False): if len(sys.argv) < 2: raise ValueError('Should pass [--gpg] as arguments') - repo_type, should_sign = unpack_args(*sys.argv) +if should_sign: raise NotImplementedError("Signing is not implemented yet") + username, password = os.getenv('DEPLOY_MAVEN_USERNAME'), os.getenv('DEPLOY_MAVEN_PASSWORD') if not username: @@ -110,7 +67,7 @@ def unpack_args(_, a, b=False): pom_file_path = "$POM_PATH" srcjar_path = "$SRCJAR_PATH" -namespace = { 'namespace': 'http://maven.apache.org/POM/4.0.0' } +namespace = {'namespace': 'http://maven.apache.org/POM/4.0.0'} root = ElementTree.parse(pom_file_path).getroot() group_id = root.find('namespace:groupId', namespace) artifact_id = root.find('namespace:artifactId', namespace) @@ -124,8 +81,11 @@ def unpack_args(_, a, b=False): version = version.text +if version != version.strip(): + raise Exception('Version "{}" has leading or trailing whitespaces'.format(version)) + snapshot = 'snapshot' -version_snapshot_regex = '^[0-9|a-f|A-F]{40}$|.*-SNAPSHOT$' +version_snapshot_regex = '^[0-9]+.[0-9]+.[0-9]+-[0-9|a-f|A-F]{40}$|.*-SNAPSHOT$' release = 'release' version_release_regex = '^[0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+)*$' @@ -141,32 +101,10 @@ def unpack_args(_, a, b=False): 'must have a version which complies to this regex: {}' .format(version, repo_type, version_release_regex)) -filename_base = '{coordinates}/{artifact}/{version}/{artifact}-{version}'.format( - coordinates=group_id.text.replace('.', '/'), version=version, artifact=artifact_id.text) - -upload_file(maven_url, username, password, jar_path, filename_base + '.jar') -if should_sign: - upload_file(maven_url, username, password, sign(jar_path), filename_base + '.jar.asc') -upload_file(maven_url, username, password, pom_file_path, filename_base + '.pom') -if should_sign: - upload_file(maven_url, username, password, sign(pom_file_path), filename_base + '.pom.asc') -if os.path.exists(srcjar_path): - upload_file(maven_url, username, password, srcjar_path, filename_base + '-sources.jar') - if should_sign: - upload_file(maven_url, username, password, sign(srcjar_path), filename_base + '-sources.jar.asc') - # TODO(vmax): use real Javadoc instead of srcjar - upload_file(maven_url, username, password, srcjar_path, filename_base + '-javadoc.jar') - if should_sign: - upload_file(maven_url, username, password, sign(srcjar_path), filename_base + '-javadoc.jar.asc') - -upload_str(maven_url, username, password, md5(pom_file_path), filename_base + '.pom.md5') -upload_str(maven_url, username, password, sha1(pom_file_path), filename_base + '.pom.sha1') -upload_str(maven_url, username, password, md5(jar_path), filename_base + '.jar.md5') -upload_str(maven_url, username, password, sha1(jar_path), filename_base + '.jar.sha1') - -if os.path.exists(srcjar_path): - upload_str(maven_url, username, password, md5(srcjar_path), filename_base + '-sources.jar.md5') - upload_str(maven_url, username, password, sha1(srcjar_path), filename_base + '-sources.jar.sha1') - - upload_str(maven_url, username, password, md5(srcjar_path), filename_base + '-javadoc.jar.md5') - upload_str(maven_url, username, password, sha1(srcjar_path), filename_base + '-javadoc.jar.sha1') +uploader = Uploader.create(username, password, maven_url) +uploader.maven(group_id.text, artifact_id.text, version, + jar_path=jar_path, pom_path=pom_file_path, + sources_path=srcjar_path if os.path.exists(srcjar_path) else None, + javadoc_path=srcjar_path if os.path.exists(srcjar_path) else None, + tests_path = None +) diff --git a/npm/assemble/rules.bzl b/npm/assemble/rules.bzl index 5894347c..112ab416 100644 --- a/npm/assemble/rules.bzl +++ b/npm/assemble/rules.bzl @@ -28,6 +28,8 @@ def _assemble_npm_impl(ctx): if len(version) == 40: # this is a commit SHA, most likely version = "0.0.0-{}".format(version) + elif 'rc' in version and '-rc' not in version: + version = version.replace('rc', '-rc') ctx.actions.run_shell( inputs = [], diff --git a/npm/deploy/BUILD b/npm/deploy/BUILD index 1dc7be4d..04c23815 100644 --- a/npm/deploy/BUILD +++ b/npm/deploy/BUILD @@ -34,9 +34,9 @@ kt_jvm_library( name = "deployer-lib", srcs = glob(["*.kt"]), deps = [ - "@vaticle_bazel_distribution//common", - "@vaticle_bazel_distribution//common/shell", - "@vaticle_bazel_distribution//common/util", + "@typedb_bazel_distribution//common", + "@typedb_bazel_distribution//common/shell", + "@typedb_bazel_distribution//common/util", "@maven//:info_picocli_picocli", "@maven//:org_zeroturnaround_zt_exec", @@ -46,6 +46,6 @@ kt_jvm_library( java_binary( name = "deployer-bin", runtime_deps = [":deployer-lib"], - main_class = "com.vaticle.bazel.distribution.npm.deploy.DeployNPMKt", + main_class = "com.typedb.bazel.distribution.npm.deploy.DeployNPMKt", visibility = ["//visibility:public"], ) diff --git a/npm/deploy/DeployNPM.kt b/npm/deploy/DeployNPM.kt index fd1e18af..c08de91b 100644 --- a/npm/deploy/DeployNPM.kt +++ b/npm/deploy/DeployNPM.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.npm.deploy +package com.typedb.bazel.distribution.npm.deploy fun main(args: Array) { Deployer(Options.of(args)).deploy() diff --git a/npm/deploy/Deployer.kt b/npm/deploy/Deployer.kt index e4e2d0bf..c3593152 100644 --- a/npm/deploy/Deployer.kt +++ b/npm/deploy/Deployer.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,18 +17,18 @@ * under the License. */ -package com.vaticle.bazel.distribution.npm.deploy +package com.typedb.bazel.distribution.npm.deploy -import com.vaticle.bazel.distribution.common.Logging.LogLevel.DEBUG -import com.vaticle.bazel.distribution.common.Logging.Logger -import com.vaticle.bazel.distribution.common.OS.LINUX -import com.vaticle.bazel.distribution.common.OS.MAC -import com.vaticle.bazel.distribution.common.shell.Shell -import com.vaticle.bazel.distribution.common.shell.Shell.Command.Companion.arg -import com.vaticle.bazel.distribution.common.util.SystemUtil.currentOS -import com.vaticle.bazel.distribution.npm.deploy.Options.Env.DEPLOY_NPM_PASSWORD -import com.vaticle.bazel.distribution.npm.deploy.Options.Env.DEPLOY_NPM_TOKEN -import com.vaticle.bazel.distribution.npm.deploy.Options.Env.DEPLOY_NPM_USERNAME +import com.typedb.bazel.distribution.common.Logging.LogLevel.DEBUG +import com.typedb.bazel.distribution.common.Logging.Logger +import com.typedb.bazel.distribution.common.OS.LINUX +import com.typedb.bazel.distribution.common.OS.MAC +import com.typedb.bazel.distribution.common.shell.Shell +import com.typedb.bazel.distribution.common.shell.Shell.Command.Companion.arg +import com.typedb.bazel.distribution.common.util.SystemUtil.currentOS +import com.typedb.bazel.distribution.npm.deploy.Options.Env.DEPLOY_NPM_PASSWORD +import com.typedb.bazel.distribution.npm.deploy.Options.Env.DEPLOY_NPM_TOKEN +import com.typedb.bazel.distribution.npm.deploy.Options.Env.DEPLOY_NPM_USERNAME import java.nio.file.Files import java.nio.file.Path import java.util.* @@ -40,11 +38,12 @@ class Deployer(private val options: Options) { fun deploy() { Shell(logger = logger, verbose = true).execute( - command = Shell.Command( - arg("npm"), arg("publish"), arg("--registry=${options.registryURL}"), - arg(authURI(options), printable = false), - arg("deploy_npm.tgz")), - env = mapOf("PATH" to pathEnv())) + command = Shell.Command( + arg(options.npmPath), arg("publish"), arg("--registry=${options.registryURL}"), + arg(authURI(options), printable = false), + arg("deploy_npm.tgz"), + ) + ) } private fun authURI(options: Options): String { @@ -89,21 +88,4 @@ class Deployer(private val options: Options) { private fun base64(string: String): String { return Base64.getEncoder().encodeToString(string.toByteArray()) } - - private fun pathEnv(): String { - val commonPaths = listOf(realPath(options.npmPath).parent) - val otherPaths = when (currentOS) { - MAC, LINUX -> listOf("/usr/bin", "/bin/") - else -> listOf() - } - return (commonPaths + otherPaths).joinToString(":") - } - - private fun realPath(path: String): Path { - val pathObj = Path.of(path) - return when (Files.exists(pathObj)) { - true -> pathObj.toRealPath() - false -> pathObj - } - } } diff --git a/npm/deploy/Options.kt b/npm/deploy/Options.kt index 6986fef6..93befe56 100644 --- a/npm/deploy/Options.kt +++ b/npm/deploy/Options.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,13 +17,13 @@ * under the License. */ -package com.vaticle.bazel.distribution.npm.deploy +package com.typedb.bazel.distribution.npm.deploy -import com.vaticle.bazel.distribution.npm.deploy.Options.CommandLineParams.NPM_PATH -import com.vaticle.bazel.distribution.npm.deploy.Options.CommandLineParams.RELEASE_REPO -import com.vaticle.bazel.distribution.npm.deploy.Options.CommandLineParams.SNAPSHOT_REPO -import com.vaticle.bazel.distribution.npm.deploy.Options.RepositoryType.RELEASE -import com.vaticle.bazel.distribution.npm.deploy.Options.RepositoryType.SNAPSHOT +import com.typedb.bazel.distribution.npm.deploy.Options.CommandLineParams.NPM_PATH +import com.typedb.bazel.distribution.npm.deploy.Options.CommandLineParams.RELEASE_REPO +import com.typedb.bazel.distribution.npm.deploy.Options.CommandLineParams.SNAPSHOT_REPO +import com.typedb.bazel.distribution.npm.deploy.Options.RepositoryType.RELEASE +import com.typedb.bazel.distribution.npm.deploy.Options.RepositoryType.SNAPSHOT import picocli.CommandLine class Options { diff --git a/npm/deploy/rules.bzl b/npm/deploy/rules.bzl index ef5c9819..46884885 100644 --- a/npm/deploy/rules.bzl +++ b/npm/deploy/rules.bzl @@ -59,11 +59,11 @@ deploy_npm = rule( ), "_npm_deployer": attr.label( allow_single_file = True, - default = "@vaticle_bazel_distribution//npm/deploy:deployer-bin_deploy.jar" + default = "@typedb_bazel_distribution//npm/deploy:deployer-bin_deploy.jar" ), "_npm_deployer_wrapper_template": attr.label( allow_single_file = True, - default = "@vaticle_bazel_distribution//npm/deploy:deploy.sh.template", + default = "@typedb_bazel_distribution//npm/deploy:deploy.sh.template", ), "_npm": attr.label( allow_single_file = True, @@ -80,9 +80,9 @@ deploy_npm = rule( ## How to generate an auth token ### Using the command line (`npm adduser`) - 1. Run `npm adduser ` (example: `npm adduser --registry=https://repo.vaticle.com/repository/npm-private`) + 1. Run `npm adduser ` (example: `npm adduser --registry=https://npm.cloudsmith.io/typedb/private/`) 2. When prompted, provide login credentials to sign in to the user account that is used in your CI and has permissions to publish the package - 3. If successful, a line will be added to your `.npmrc` file (`$HOME/.npmrc` on Unix) which looks like: `//repo.vaticle.com/repository/npm-snapshot/:_authToken=NpmToken.00000000-0000-0000-0000-000000000000`. The token is the value of `_authToken`, in this case `NpmToken.00000000-0000-0000-0000-000000000000`. + 3. If successful, a line will be added to your `.npmrc` file (`$HOME/.npmrc` on Unix) which looks like: `//npm.cloudsmith.io/typedb/private/:_authToken=NpmToken.00000000-0000-0000-0000-000000000000`. The token is the value of `_authToken`, in this case `NpmToken.00000000-0000-0000-0000-000000000000`. 4. Save the auth token somewhere safe and then delete it from your `.npmrc` file ### Using a UI diff --git a/nuget/BUILD b/nuget/BUILD new file mode 100644 index 00000000..13a83393 --- /dev/null +++ b/nuget/BUILD @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. diff --git a/nuget/rules.bzl b/nuget/rules.bzl new file mode 100644 index 00000000..2fd243c9 --- /dev/null +++ b/nuget/rules.bzl @@ -0,0 +1,354 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. + +# This file is based on the original implementation of https://github.com/SeleniumHQ/selenium/. + +load("@rules_dotnet//dotnet/private:common.bzl", "is_debug") +load("@rules_dotnet//dotnet/private:providers.bzl", "DotnetAssemblyRuntimeInfo") + +# The change to the PATH is recommended here: +# https://learn.microsoft.com/en-us/dotnet/core/install/linux-scripted-manual?source=recommendations#set-environment-variables-system-wide +# We list our .Net installation first because we +# want it to be picked up first + +# The `MSBuildEnableWorkloadResolver` is disabled to prevent warnings +# about a missing Microsoft.NET.SDK.WorkloadAutoImportPropsLocator + +def _dotnet_preamble(toolchain): + return """ +export DOTNET="$(pwd)/{dotnet}" +export DOTNET_CLI_HOME="$(dirname $DOTNET)" +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_NOLOGO=1 +export DOTNET_ROOT="$(dirname $DOTNET)" +export PATH=$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH +export MSBuildEnableWorkloadResolver=false +export CWD=$(pwd) + +# Required to make packing work on Windows +export APPDATA="$(pwd)" +export PROGRAMFILES="$(pwd)" + +# Required to make NuGet tool work on non-writable home path like GitHub actions +export XDG_DATA_HOME=$(mktemp -d) + +# Create `global.json` to trick .Net into using the hermetic toolchain +# https://learn.microsoft.com/en-us/dotnet/core/tools/global-json +echo '{{"sdk": {{"version": "{version}"}} }}' >$(pwd)/global.json + +""".format( + dotnet = toolchain.runtime.files_to_run.executable.path, + version = toolchain.dotnetinfo.sdk_version, + ) + + +def _check_platform(platform): + allowed_values = ("osx-arm64", "osx-x64", "linux-arm64", "linux-x64", "win-arm64", "win-x64") + if platform not in allowed_values: + fail("Platform must be set to any of {}. Got {} instead!".format(allowed_values, platform)) + + +def _parse_version(ctx): + version = ctx.attr.version + if not version: + version = ctx.var.get("version", "0.0.0") + + return version + + +def _nuget_pack_impl(ctx): + version = _parse_version(ctx) + nuspec = ctx.actions.declare_file("{}-generated.nuspec".format(ctx.label.name)) + + # A mapping of files to the paths in which we expect to find them in the package + paths = {} + native_lib_declrs = "" + + if ctx.attr.platform: + platform_suffix = ".{}".format(ctx.attr.platform) + else: + platform_suffix = "" + + package_name = "{}{}".format(ctx.attr.id, platform_suffix) + + if ctx.files.native_libs: + _check_platform(ctx.attr.platform) + native_target_dir = "runtimes/{}/native".format(ctx.attr.platform) + + for native_lib in ctx.files.native_libs: + paths[native_lib] = native_lib.short_path + native_lib_declrs += """ +""".format(native_lib.short_path, native_target_dir) + + ctx.actions.expand_template( + template = ctx.file.nuspec_template, + output = nuspec, + substitutions = { + "$packageid$": package_name, + "$version$": version, + "$native_lib_declrs$": native_lib_declrs, + "$target_framework$": ctx.attr.target_framework, + }, + ) + + build_flavor = "Debug" if is_debug(ctx) else "Release" + + for (lib, name) in ctx.attr.libs.items(): + assembly_info = lib[DotnetAssemblyRuntimeInfo] + + for dll in assembly_info.libs: + paths[dll] = "lib/{}/{}.dll".format(ctx.attr.target_framework, name) + for pdb in assembly_info.pdbs: + paths[pdb] = "lib/{}/{}.pdb".format(ctx.attr.target_framework, name) + for doc in assembly_info.xml_docs: + paths[doc] = "lib/{}/{}.xml".format(ctx.attr.target_framework, name) + + csproj_template = """ + + {} + {} + {} + + +""".format(ctx.attr.target_framework, package_name, ctx.attr.id) + + csproj_file = ctx.actions.declare_file("{}-generated.csproj".format(ctx.label.name)) + ctx.actions.write(csproj_file, csproj_template) + paths[csproj_file] = "project.csproj" + + for (file, name) in ctx.attr.files.items(): + paths[file.files.to_list()[0]] = name + + # Zip everything up so we have the right file structure + zip_file = ctx.actions.declare_file("{}-intermediate.zip".format(ctx.label.name)) + args = ctx.actions.args() + args.add_all(["Cc", zip_file]) + for (file, path) in paths.items(): + args.add("{}={}".format(path, file.path)) + args.add("project.nuspec={}".format(nuspec.path)) + + ctx.actions.run( + executable = ctx.executable._zip, + arguments = [args], + inputs = paths.keys() + [nuspec], + outputs = [zip_file], + ) + + # Now lay everything out on disk and execute the dotnet pack rule + + # Now we have everything, let's build our package + toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] + + nupkg_name_stem = "{}.{}".format(package_name, version) + + dotnet = toolchain.runtime.files_to_run.executable + pkg = ctx.actions.declare_file("{}.nupkg".format(nupkg_name_stem)) + symbols_pkg = ctx.actions.declare_file("{}.snupkg".format(nupkg_name_stem)) + + # Prepare our cache of nupkg files + packages = ctx.actions.declare_directory("{}-nuget-packages".format(ctx.label.name)) + packages_cmd = "mkdir -p {} ".format(packages.path) + + transitive_libs = depset(transitive = [l[DotnetAssemblyRuntimeInfo].deps for l in ctx.attr.libs]).to_list() + package_files = depset([lib.nuget_info.nupkg for lib in transitive_libs if lib.nuget_info]).to_list() + + if len(package_files): + packages_cmd += "&& cp " + " ".join([f.path for f in package_files]) + " " + packages.path + + ctx.actions.run_shell( + outputs = [packages], + inputs = package_files, + command = packages_cmd, + mnemonic = "LayoutNugetPackages", + ) + + cmd = _dotnet_preamble(toolchain) + \ + "mkdir {}-working-dir && ".format(ctx.label.name) + \ + "echo $(pwd) && " + \ + "$(location @bazel_tools//tools/zip:zipper) x {} -d {}-working-dir && ".format(zip_file.path, ctx.label.name) + \ + "cd {}-working-dir && ".format(ctx.label.name) + \ + "echo '' >nuget.config && ".format(packages.path) + \ + "$DOTNET restore --no-dependencies && " + \ + "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration={} -p:PackageId={} -p:Version={} -p:PackageVersion={} -p:NuspecProperties=\"version={}\" && ".format(build_flavor, package_name, version, version, version) + \ + "cp bin/{}/{}.{}.nupkg ../{} && ".format(build_flavor, package_name, version, pkg.path) + \ + "cp bin/{}/{}.{}.snupkg ../{}".format(build_flavor, package_name, version, symbols_pkg.path) + + cmd = ctx.expand_location( + cmd, + targets = [ + ctx.attr._zip, + ], + ) + + ctx.actions.run_shell( + outputs = [pkg, symbols_pkg], + inputs = [ + zip_file, + dotnet, + packages, + ], + tools = [ctx.executable._zip, dotnet] + + toolchain.default.files.to_list() + + toolchain.runtime.default_runfiles.files.to_list() + + toolchain.runtime.data_runfiles.files.to_list(), + command = cmd, + mnemonic = "CreateNupkg", + ) + + return [ + DefaultInfo( + files = depset([pkg, symbols_pkg]), + runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), + ), + ] + +nuget_pack = rule( + _nuget_pack_impl, + attrs = { + "id": attr.string( + doc = "Nuget ID of the package", + mandatory = True, + ), + "version": attr.string( + doc = """ + Target package's version. + Alternatively, pass --define version=VERSION to Bazel invocation. + Not specifying version at all defaults to '0.0.0' + """, + ), + "libs": attr.label_keyed_string_dict( + doc = "The .Net libraries that are being published", + providers = [DotnetAssemblyRuntimeInfo], + ), + "files": attr.label_keyed_string_dict( + doc = "Mapping of files to paths within the nuget package", + allow_empty = True, + allow_files = True, + ), + "platform": attr.string( + doc = "Target platform and architecture for platform-specific packages: {platform}-{arch}.", + default = "", + ), + "native_libs": attr.label_list( + doc = "Native libs to include into the package", + ), + "target_framework": attr.string( + doc = "Target C# build framework", + mandatory = True, + ), + "property_group_vars": attr.string_dict( + doc = "Keys and values for variables declared in `PropertyGroup`s in the `csproj_file`", + allow_empty = True, + ), + "nuspec_template": attr.label( + doc = "Template .nuspec file with the project description", + mandatory = True, + allow_single_file = True, + ), + "_zip": attr.label( + default = "@bazel_tools//tools/zip:zipper", + executable = True, + cfg = "exec", + ), + }, + toolchains = ["@rules_dotnet//dotnet:toolchain_type"], +) + +def _nuget_push_impl(ctx): + all_srcs = ctx.attr.src.files.to_list() + + package_files = [] + for package_file in ctx.attr.src.files.to_list(): + if package_file.extension == "snupkg": + continue # .snupkg are automatically included by the nuget push command if they are in the same dir + package_files.append(package_file) + + toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] + dotnet_runtime = toolchain.runtime.files_to_run.executable + + package_file_paths = [] + for package_file in package_files: + package_file_paths.append(ctx.expand_location(package_file.short_path)) + + push_file = ctx.actions.declare_file(ctx.attr.script_file_name) + + ctx.actions.expand_template( + template = ctx.file._push_script_template, + output = push_file, + substitutions = { + '{dotnet_runtime_path}': dotnet_runtime.path, + '{nupkg_paths}': " ".join(package_file_paths), + '{snapshot_url}': ctx.attr.snapshot_url, + '{release_url}': ctx.attr.release_url, + }, + is_executable = True, + ) + + return DefaultInfo( + executable = push_file, + runfiles = ctx.runfiles(files = all_srcs + toolchain.dotnetinfo.runtime_files), + ) + + +_nuget_push = rule( + implementation = _nuget_push_impl, + executable = True, + attrs = { + "src": attr.label( + allow_files = [".nupkg", ".snupkg"], + doc = "Nuget packages (and their debug symbol packages) to push", + ), + "snapshot_url" : attr.string( + mandatory = True, + doc = "URL of the target snapshot repository", + ), + "release_url" : attr.string( + mandatory = True, + doc = "URL of the target release repository", + ), + "script_file_name": attr.string( + mandatory = True, + doc = "Name of instantiated deployment script" + ), + "_push_script_template": attr.label( + allow_single_file = True, + default = "//nuget/templates:push.py", + ), + }, + toolchains = [ + "@rules_dotnet//dotnet:toolchain_type", + ], +) + +def nuget_push(name, src, snapshot_url, release_url, **kwargs): + push_script_name = "{}_script".format(name) + push_script_file_name = "{}-push.py".format(push_script_name) + + _nuget_push( + name = push_script_name, + script_file_name = push_script_file_name, + src = src, + snapshot_url = snapshot_url, + release_url = release_url, + **kwargs + ) + + native.py_binary( + name = name, + srcs = [push_script_name], + main = push_script_file_name + ) diff --git a/nuget/templates/BUILD b/nuget/templates/BUILD new file mode 100644 index 00000000..40a59922 --- /dev/null +++ b/nuget/templates/BUILD @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. + +exports_files(["push.py"]) diff --git a/nuget/templates/push.py b/nuget/templates/push.py new file mode 100644 index 00000000..07de5616 --- /dev/null +++ b/nuget/templates/push.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, 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. + +import os +import subprocess +import sys + +def unpack_args(_, arg1): + return arg1 + +if len(sys.argv) < 2: + raise ValueError("Should pass as arguments") + +repo_type = unpack_args(*sys.argv) + +nuget_repositories = { + "snapshot": "{snapshot_url}", + "release": "{release_url}", +} +target_repo_url = nuget_repositories[repo_type] + +api_key = os.getenv('DEPLOY_NUGET_API_KEY') + +if not api_key: + raise ValueError('Error: API key should be passed via $DEPLOY_NUGET_API_KEY env variable') + +args = [ + "{dotnet_runtime_path}", + "nuget", + "push", +] +args += "{nupkg_paths}".split() +args += [ + "-k", + f"{api_key}", + "-s", + f"{target_repo_url}", +] + +print(f"Executing nuget push for {nupkg_paths}...") + +subprocess.check_call(args) + +print("Done executing nuget push!") diff --git a/packer/deps.bzl b/packer/deps.bzl index bd2bf8ca..7661375f 100644 --- a/packer/deps.bzl +++ b/packer/deps.bzl @@ -19,17 +19,18 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # under the License. # -def deps(): +def packer_osx(): http_archive( name = "packer_osx", - url = "https://releases.hashicorp.com/packer/1.7.4/packer_1.7.4_darwin_amd64.zip", - sha256 = "f3faf9dce0cebdfc7abfcf70511c6230e0c0a5c499ca3478def81549ded91b20", - build_file_content = 'exports_files(["packer"])' + build_file_content = 'exports_files(["packer"])', + url = "https://releases.hashicorp.com/packer/1.8.3/packer_1.8.3_darwin_amd64.zip", + sha256 = "ef1ceaaafcdada65bdbb45793ad6eedbc7c368d415864776b9d3fa26fb30b896" ) +def packer_linux(): http_archive( name = "packer_linux", - url = "https://releases.hashicorp.com/packer/1.7.4/packer_1.7.4_linux_amd64.zip", - sha256 = "3660064a56a174a6da5c37ee6b36107098c6b37e35cc84feb2f7f7519081b1b0", - build_file_content = 'exports_files(["packer"])' + build_file_content = 'exports_files(["packer"])', + url = "https://releases.hashicorp.com/packer/1.8.3/packer_1.8.3_linux_amd64.zip", + sha256 = "0587f7815ed79589cd9c2b754c82115731c8d0b8fd3b746fe40055d969facba5" ) diff --git a/packer/rules.bzl b/packer/rules.bzl index 545d02b8..7457cf43 100644 --- a/packer/rules.bzl +++ b/packer/rules.bzl @@ -74,7 +74,7 @@ deploy_packer = rule( ), "_deployment_script_template": attr.label( allow_single_file = True, - default = "@vaticle_bazel_distribution//packer/templates:deploy_packer.py", + default = "@typedb_bazel_distribution//packer/templates:deploy_packer.py", ), "_packer": attr.label_list( allow_files = True, diff --git a/pip/BUILD b/pip/BUILD index adf2e46d..43e60097 100644 --- a/pip/BUILD +++ b/pip/BUILD @@ -20,17 +20,17 @@ exports_files(["replace_imports.py", "requirements.txt"]) load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load("@vaticle_bazel_distribution_pip//:requirements.bzl", vaticle_bazel_distribution_requirement = "requirement") +load("@typedb_bazel_distribution_pip//:requirements.bzl", typedb_bazel_distribution_requirement = "requirement") bzl_library( name = "lib", srcs = [ "rules.bzl", - "@vaticle_bazel_distribution_pip//:requirements.bzl", - "@rules_python//:bzl", - "@rules_python//:version.bzl", - "@bazel_skylib//lib:versions", + ], + deps = [ + "@typedb_bazel_distribution_pip//:requirements.bzl", + "@rules_python//python:pip_bzl", ], visibility = ["//visibility:public"] ) @@ -39,8 +39,8 @@ py_binary( name = "assemble", srcs = ["assemble.py"], deps = [ - vaticle_bazel_distribution_requirement("setuptools"), - vaticle_bazel_distribution_requirement("wheel") + typedb_bazel_distribution_requirement("setuptools"), + typedb_bazel_distribution_requirement("wheel") ], visibility = ["//visibility:public"] ) diff --git a/pip/deps.bzl b/pip/deps.bzl index 30edc85a..5166e8a9 100644 --- a/pip/deps.bzl +++ b/pip/deps.bzl @@ -1,7 +1,7 @@ load("@rules_python//python:pip.bzl", "pip_parse") -def deps(): +def typedb_bazel_distribution_pip(): pip_parse( - name = "vaticle_bazel_distribution_pip", - requirements_lock = "@vaticle_bazel_distribution//pip:requirements.txt", + name = "typedb_bazel_distribution_pip", + requirements_lock = "@typedb_bazel_distribution//pip:requirements.txt", ) diff --git a/pip/rules.bzl b/pip/rules.bzl index e2043b1c..f48cccfb 100644 --- a/pip/rules.bzl +++ b/pip/rules.bzl @@ -17,7 +17,7 @@ # under the License. # -load("@vaticle_bazel_distribution_pip//:requirements.bzl", vaticle_bazel_distribution_requirement = "requirement") +load("@typedb_bazel_distribution_pip//:requirements.bzl", typedb_bazel_distribution_requirement = "requirement") def _python_repackage_impl(ctx): @@ -137,6 +137,18 @@ def _assemble_pip_impl(ctx): if len(version) == 40: # this is a commit SHA, most likely version = "0.0.0+{}".format(version) + elif '-alpha-' in version: + version = version.replace('-alpha-', 'a') + elif '-alpha' in version: + version = version.replace('-alpha', 'a') + elif '-beta-' in version: + version = version.replace('-beta-', 'b') + elif '-beta' in version: + version = version.replace('-beta', 'b') + elif '-rc-' in version: + version = version.replace('-rc-', 'rc') + elif '-rc' in version: + version = version.replace('-rc', 'rc') ctx.actions.run_shell( inputs = [], @@ -343,23 +355,23 @@ _deploy_pip = rule( ), "_deps": attr.label_list( default = [ - vaticle_bazel_distribution_requirement("twine"), - vaticle_bazel_distribution_requirement("setuptools"), - vaticle_bazel_distribution_requirement("wheel"), - vaticle_bazel_distribution_requirement("requests"), - vaticle_bazel_distribution_requirement("urllib3"), - vaticle_bazel_distribution_requirement("chardet"), - vaticle_bazel_distribution_requirement("certifi"), - vaticle_bazel_distribution_requirement("idna"), - vaticle_bazel_distribution_requirement("tqdm"), - vaticle_bazel_distribution_requirement("requests_toolbelt"), - vaticle_bazel_distribution_requirement("pkginfo"), - vaticle_bazel_distribution_requirement("readme_renderer"), - vaticle_bazel_distribution_requirement("Pygments"), - vaticle_bazel_distribution_requirement("docutils"), - vaticle_bazel_distribution_requirement("bleach"), - vaticle_bazel_distribution_requirement("webencodings"), - vaticle_bazel_distribution_requirement("packaging") + typedb_bazel_distribution_requirement("twine"), + typedb_bazel_distribution_requirement("setuptools"), + typedb_bazel_distribution_requirement("wheel"), + typedb_bazel_distribution_requirement("requests"), + typedb_bazel_distribution_requirement("urllib3"), + typedb_bazel_distribution_requirement("chardet"), + typedb_bazel_distribution_requirement("certifi"), + typedb_bazel_distribution_requirement("idna"), + typedb_bazel_distribution_requirement("tqdm"), + typedb_bazel_distribution_requirement("requests_toolbelt"), + typedb_bazel_distribution_requirement("pkginfo"), + typedb_bazel_distribution_requirement("readme_renderer"), + typedb_bazel_distribution_requirement("Pygments"), + typedb_bazel_distribution_requirement("docutils"), + typedb_bazel_distribution_requirement("bleach"), + typedb_bazel_distribution_requirement("webencodings"), + typedb_bazel_distribution_requirement("packaging") ] ) }, diff --git a/platform/BUILD b/platform/BUILD index edc49ac1..59b2a99e 100644 --- a/platform/BUILD +++ b/platform/BUILD @@ -1,7 +1,5 @@ # -# Copyright (C) 2022 Vaticle -# -# This program is free software: you can redistribute it and/or modify +# This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. diff --git a/platform/constraints.bzl b/platform/constraints.bzl index 3a15411f..c978500b 100644 --- a/platform/constraints.bzl +++ b/platform/constraints.bzl @@ -1,7 +1,5 @@ # -# Copyright (C) 2022 Vaticle -# -# This program is free software: you can redistribute it and/or modify +# This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. diff --git a/platform/jvm/AppleCodeSigner.kt b/platform/jvm/AppleCodeSigner.kt index dcd0314f..11be6b97 100644 --- a/platform/jvm/AppleCodeSigner.kt +++ b/platform/jvm/AppleCodeSigner.kt @@ -1,36 +1,31 @@ -package com.vaticle.bazel.distribution.platform.jvm - -import com.vaticle.bazel.distribution.common.shell.Shell -import com.vaticle.bazel.distribution.common.util.FileUtil.listFilesRecursively -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.ENTITLEMENTS -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.FORCE -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.OPTIONS -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.SIGN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.STRICT -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.TIMESTAMP -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.VERIFY -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Paths.CONTENTS -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Paths.MAC_OS -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Paths.RUNTIME -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Paths.TMP -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.CN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.CREATE_KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.DEFAULT_KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.DELETE_KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.IMPORT -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.LIST_KEYCHAINS -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.LOGIN_KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.PKCS12 -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.SET_KEY_PARTITION_LIST -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.UNLOCK_KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.USER -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Security.USR_BIN_CODESIGN -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Extensions.DYLIB -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Extensions.JAR -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Extensions.JNILIB -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.CODESIGN -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.SECURITY +package com.typedb.bazel.distribution.platform.jvm + +import com.typedb.bazel.distribution.common.shell.Shell +import com.typedb.bazel.distribution.common.util.FileUtil.listFilesRecursively +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.ENTITLEMENTS +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.FORCE +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.OPTIONS +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.SIGN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Codesign.Args.TIMESTAMP +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Paths.TMP +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.CN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.CREATE_KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.DEFAULT_KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.DELETE_KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.IMPORT +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.LIST_KEYCHAINS +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.LOGIN_KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.PKCS12 +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.SET_KEY_PARTITION_LIST +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.UNLOCK_KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.USER +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Security.USR_BIN_CODESIGN +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Extensions.DYLIB +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Extensions.JAR +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Extensions.JNILIB +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.CODESIGN +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.SECURITY import org.zeroturnaround.exec.ProcessResult import java.io.File import java.io.FileInputStream @@ -140,7 +135,7 @@ class AppleCodeSigner(private val shell: Shell, private val macEntitlements: Fil val nativeLibs = tmpDir.listFilesRecursively().filter { it.extension in listOf(JNILIB, DYLIB) } if (nativeLibs.isNotEmpty()) { - nativeLibs.forEach { signFile(file = it, skipIfSigned = true) } + nativeLibs.forEach { signFile(file = it) } jar.setWritable(true) jar.delete() shell.execute(listOf(ShellArgs.Programs.JAR, "cMf", "../${jar.path}", "."), baseDir = tmpPath) @@ -150,18 +145,7 @@ class AppleCodeSigner(private val shell: Shell, private val macEntitlements: Fil } } - fun signFile(file: File, skipIfSigned: Boolean = false) { - if (skipIfSigned) { - val verifySignatureResult = VerifySignatureResult( - shell.execute(listOf(CODESIGN, VERIFY, STRICT, file.path), throwOnError = false) - ) - if (verifySignatureResult.status == VerifySignatureResult.Status.SIGNED) return - else if (verifySignatureResult.status == VerifySignatureResult.Status.ERROR) { - throw IllegalStateException("Command '${CODESIGN}' failed with exit code " + - "${verifySignatureResult.exitValue} and output: ${verifySignatureResult.outputString()}") - } - } - + fun signFile(file: File) { file.setWritable(true) val signCommand: MutableList = mutableListOf( CODESIGN, SIGN, certSubject, diff --git a/platform/jvm/BUILD b/platform/jvm/BUILD index 41627612..dfaa2b71 100644 --- a/platform/jvm/BUILD +++ b/platform/jvm/BUILD @@ -32,9 +32,9 @@ kt_jvm_library( name = "assembler-lib", srcs = glob(["*.kt"]), deps = [ - "@vaticle_bazel_distribution//common", - "@vaticle_bazel_distribution//common/shell", - "@vaticle_bazel_distribution//common/util", + "@typedb_bazel_distribution//common", + "@typedb_bazel_distribution//common/shell", + "@typedb_bazel_distribution//common/util", "@maven//:info_picocli_picocli", "@maven//:org_zeroturnaround_zt_exec", @@ -44,7 +44,7 @@ kt_jvm_library( java_binary( name = "assembler-bin", runtime_deps = [":assembler-lib"], - main_class = "com.vaticle.bazel.distribution.platform.jvm.MainKt", + main_class = "com.typedb.bazel.distribution.platform.jvm.MainKt", visibility = ["//visibility:public"], ) diff --git a/platform/jvm/CommandLineParams.kt b/platform/jvm/CommandLineParams.kt index aa643809..85daa3b2 100644 --- a/platform/jvm/CommandLineParams.kt +++ b/platform/jvm/CommandLineParams.kt @@ -1,10 +1,10 @@ -package com.vaticle.bazel.distribution.platform.jvm +package com.typedb.bazel.distribution.platform.jvm -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_CODE_SIGNING_CERT_PASSWORD -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID_PASSWORD -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_TEAM_ID -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.CONFIG_PATH +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_CODE_SIGNING_CERT_PASSWORD +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID_PASSWORD +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_TEAM_ID +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.CONFIG_PATH import picocli.CommandLine import java.io.File diff --git a/platform/jvm/JVMPlatformAssembler.kt b/platform/jvm/JVMPlatformAssembler.kt index fb66815e..4b99429f 100644 --- a/platform/jvm/JVMPlatformAssembler.kt +++ b/platform/jvm/JVMPlatformAssembler.kt @@ -1,43 +1,43 @@ -package com.vaticle.bazel.distribution.platform.jvm - -import com.vaticle.bazel.distribution.common.Logging.Logger -import com.vaticle.bazel.distribution.common.OS.LINUX -import com.vaticle.bazel.distribution.common.OS.MAC -import com.vaticle.bazel.distribution.common.OS.WINDOWS -import com.vaticle.bazel.distribution.common.shell.Shell -import com.vaticle.bazel.distribution.common.util.FileUtil.listFilesRecursively -import com.vaticle.bazel.distribution.common.util.SystemUtil.currentOS -import com.vaticle.bazel.distribution.platform.jvm.AppleCodeSigner.Companion.KEYCHAIN_NAME -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.InputFiles.Paths.JDK -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.InputFiles.Paths.SRC -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.InputFiles.Paths.WIX_TOOLSET -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.APP_IMAGE -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.APP_VERSION -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.COPYRIGHT -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.DESCRIPTION -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.DEST -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.ICON -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.INPUT -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LICENSE_FILE -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LINUX_APP_CATEGORY -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LINUX_MENU_GROUP -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LINUX_SHORTCUT -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAC_SIGN -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAC_SIGNING_KEYCHAIN -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAIN_CLASS -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAIN_JAR -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.NAME -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.TYPE -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.VENDOR -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.VERBOSE -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.WIN_MENU -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.WIN_MENU_GROUP -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.WIN_SHORTCUT -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.Windows.Env.PATH -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.JAR -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.JPACKAGE -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.JPACKAGE_EXE -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.TAR +package com.typedb.bazel.distribution.platform.jvm + +import com.typedb.bazel.distribution.common.Logging.Logger +import com.typedb.bazel.distribution.common.OS.LINUX +import com.typedb.bazel.distribution.common.OS.MAC +import com.typedb.bazel.distribution.common.OS.WINDOWS +import com.typedb.bazel.distribution.common.shell.Shell +import com.typedb.bazel.distribution.common.util.FileUtil.listFilesRecursively +import com.typedb.bazel.distribution.common.util.SystemUtil.currentOS +import com.typedb.bazel.distribution.platform.jvm.AppleCodeSigner.Companion.KEYCHAIN_NAME +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.InputFiles.Paths.JDK +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.InputFiles.Paths.SRC +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.InputFiles.Paths.WIX_TOOLSET +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.APP_IMAGE +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.APP_VERSION +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.COPYRIGHT +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.DESCRIPTION +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.DEST +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.ICON +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.INPUT +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LICENSE_FILE +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LINUX_APP_CATEGORY +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LINUX_MENU_GROUP +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.LINUX_SHORTCUT +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAC_SIGN +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAC_SIGNING_KEYCHAIN +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAIN_CLASS +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.MAIN_JAR +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.NAME +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.TYPE +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.VENDOR +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.VERBOSE +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.WIN_MENU +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.WIN_MENU_GROUP +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.JPackageArgs.WIN_SHORTCUT +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.PlatformImageBuilder.Windows.Env.PATH +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.JAR +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.JPACKAGE +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.JPACKAGE_EXE +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.TAR import java.io.File import java.lang.System.getenv import java.nio.file.Files @@ -230,8 +230,10 @@ object JVMPlatformAssembler { null -> logger.debug { "Skipping notarizing step: Apple code signing is not enabled" } else -> { MacAppNotarizer( - dmgPath = Path.of(distDir.path, "${options.image.filename}-$version.dmg") - ).notarize(codeSigningOptions) + dmgPath = Path.of(distDir.path, "${options.image.filename}-$version.dmg"), + appleCodeSigning = codeSigningOptions, + logging = options.logging, + ).notarize() appleCodeSigner!!.deleteKeychain() } } diff --git a/platform/jvm/MacAppNotarizer.kt b/platform/jvm/MacAppNotarizer.kt index 57f0c720..b3210e93 100644 --- a/platform/jvm/MacAppNotarizer.kt +++ b/platform/jvm/MacAppNotarizer.kt @@ -1,39 +1,49 @@ -package com.vaticle.bazel.distribution.platform.jvm +package com.typedb.bazel.distribution.platform.jvm -import com.vaticle.bazel.distribution.common.shell.Shell -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.shell -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.APPLE_ID -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.NOTARYTOOL -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.ONE_HOUR -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.PASSWORD -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.STAPLE -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.STAPLER -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.SUBMIT -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.TEAM_ID -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.TIMEOUT -import com.vaticle.bazel.distribution.platform.jvm.MacAppNotarizer.Args.WAIT -import com.vaticle.bazel.distribution.platform.jvm.ShellArgs.Programs.XCRUN +import com.typedb.bazel.distribution.common.Logging.LogLevel +import com.typedb.bazel.distribution.common.Logging.LogLevel.DEBUG +import com.typedb.bazel.distribution.common.Logging.LogLevel.ERROR +import com.typedb.bazel.distribution.common.Logging.Logger +import com.typedb.bazel.distribution.common.shell.Shell +import com.typedb.bazel.distribution.common.shell.Shell.Command.Companion.arg +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.shell +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.APPLE_ID +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.NOTARYTOOL +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.ONE_HOUR +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.PASSWORD +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.STAPLE +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.STAPLER +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.SUBMIT +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.TEAM_ID +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.TIMEOUT +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.VERBOSE +import com.typedb.bazel.distribution.platform.jvm.MacAppNotarizer.Args.WAIT +import com.typedb.bazel.distribution.platform.jvm.ShellArgs.Programs.XCRUN import java.nio.file.Path -class MacAppNotarizer(private val dmgPath: Path) { - fun notarize(appleCodeSigning: Options.AppleCodeSigning) { - shell.execute(notarizeCommand(appleCodeSigning)).outputString() +class MacAppNotarizer( + private val dmgPath: Path, appleCodeSigning: Options.AppleCodeSigning, private val logging: Options.Logging +) { + private val logger = Logger(logLevel = if (logging.verbose) DEBUG else ERROR) + + fun notarize() { + shell.execute(notarizeCommand).outputString() + logger.debug { "\nUse `xcrun notarytool log ` to view further information about this notarization\n" } markPackageAsApproved() } - private fun notarizeCommand(appleCodeSigning: Options.AppleCodeSigning): Shell.Command { - return Shell.Command( - Shell.Command.arg(XCRUN), Shell.Command.arg(NOTARYTOOL), Shell.Command.arg(SUBMIT), - Shell.Command.arg(APPLE_ID), Shell.Command.arg(appleCodeSigning.appleID), - Shell.Command.arg(PASSWORD), Shell.Command.arg(appleCodeSigning.appleIDPassword, printable = false), - Shell.Command.arg(TEAM_ID), Shell.Command.arg(appleCodeSigning.appleTeamID, printable = false), - Shell.Command.arg(WAIT), Shell.Command.arg(TIMEOUT), Shell.Command.arg(ONE_HOUR), - Shell.Command.arg(dmgPath.toString()), - ) - } + private val notarizeCommand = Shell.Command(listOfNotNull( + arg(XCRUN), arg(NOTARYTOOL), arg(SUBMIT), + if (logging.verbose) arg(VERBOSE) else null, + arg(APPLE_ID), arg(appleCodeSigning.appleID), + arg(PASSWORD), arg(appleCodeSigning.appleIDPassword, printable = false), + arg(TEAM_ID), arg(appleCodeSigning.appleTeamID, printable = false), + arg(WAIT), arg(TIMEOUT), arg(ONE_HOUR), + arg(dmgPath.toString()), + )) private fun markPackageAsApproved() { - shell.execute(listOf(XCRUN, STAPLER, STAPLE, dmgPath.toString())) + shell.execute(listOfNotNull(XCRUN, STAPLER, STAPLE, if (logging.verbose) VERBOSE else null, dmgPath.toString())) } private object Args { @@ -46,6 +56,7 @@ class MacAppNotarizer(private val dmgPath: Path) { const val SUBMIT = "submit" const val TIMEOUT = "--timeout" const val TEAM_ID = "--team-id" + const val VERBOSE = "-v" const val WAIT = "--wait" } } diff --git a/platform/jvm/Main.kt b/platform/jvm/Main.kt index 9578be9f..d3842e4d 100644 --- a/platform/jvm/Main.kt +++ b/platform/jvm/Main.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,7 +17,7 @@ * under the License. */ -package com.vaticle.bazel.distribution.platform.jvm +package com.typedb.bazel.distribution.platform.jvm import picocli.CommandLine diff --git a/platform/jvm/Options.kt b/platform/jvm/Options.kt index 91eb4f82..850167ae 100644 --- a/platform/jvm/Options.kt +++ b/platform/jvm/Options.kt @@ -1,6 +1,4 @@ /* - * Copyright (C) 2022 Vaticle - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,44 +17,44 @@ * under the License. */ -package com.vaticle.bazel.distribution.platform.jvm - -import com.vaticle.bazel.distribution.common.Logging.Logger -import com.vaticle.bazel.distribution.common.Logging.LogLevel -import com.vaticle.bazel.distribution.common.util.PropertiesUtil.getBooleanOrDefault -import com.vaticle.bazel.distribution.common.util.PropertiesUtil.getStringOrNull -import com.vaticle.bazel.distribution.common.util.PropertiesUtil.requireString -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_CODE_SIGNING_CERT_PASSWORD -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID_PASSWORD -import com.vaticle.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_TEAM_ID -import com.vaticle.bazel.distribution.platform.jvm.JVMPlatformAssembler.logger -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.APPLE_CODE_SIGN -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.APPLE_CODE_SIGNING_CERT_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.APPLE_DEEP_SIGN_JARS_REGEX -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.COPYRIGHT -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.CREATE_SHORTCUT -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.ICON_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.DESCRIPTION -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.IMAGE_FILENAME -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.IMAGE_NAME -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.JARS_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.VENDOR -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.JDK_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.LICENSE_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.LINUX_APP_CATEGORY -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.LINUX_MENU_GROUP -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.MAC_APP_ID -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.MAC_ENTITLEMENTS_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.MAIN_CLASS -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.MAIN_JAR_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.OUTPUT_ARCHIVE_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.LOG_SENSITIVE_DATA -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.SOURCE_FILENAME -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.VERBOSE -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.VERSION_FILE_PATH -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.WINDOWS_MENU_GROUP -import com.vaticle.bazel.distribution.platform.jvm.Options.Keys.WINDOWS_WIX_TOOLSET_PATH +package com.typedb.bazel.distribution.platform.jvm + +import com.typedb.bazel.distribution.common.Logging.Logger +import com.typedb.bazel.distribution.common.Logging.LogLevel +import com.typedb.bazel.distribution.common.util.PropertiesUtil.getBooleanOrDefault +import com.typedb.bazel.distribution.common.util.PropertiesUtil.getStringOrNull +import com.typedb.bazel.distribution.common.util.PropertiesUtil.requireString +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_CODE_SIGNING_CERT_PASSWORD +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_ID_PASSWORD +import com.typedb.bazel.distribution.platform.jvm.CommandLineParams.Keys.APPLE_TEAM_ID +import com.typedb.bazel.distribution.platform.jvm.JVMPlatformAssembler.logger +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.APPLE_CODE_SIGN +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.APPLE_CODE_SIGNING_CERT_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.APPLE_DEEP_SIGN_JARS_REGEX +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.COPYRIGHT +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.CREATE_SHORTCUT +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.ICON_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.DESCRIPTION +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.IMAGE_FILENAME +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.IMAGE_NAME +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.JARS_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.VENDOR +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.JDK_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.LICENSE_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.LINUX_APP_CATEGORY +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.LINUX_MENU_GROUP +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.MAC_APP_ID +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.MAC_ENTITLEMENTS_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.MAIN_CLASS +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.MAIN_JAR_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.OUTPUT_ARCHIVE_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.LOG_SENSITIVE_DATA +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.SOURCE_FILENAME +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.VERBOSE +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.VERSION_FILE_PATH +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.WINDOWS_MENU_GROUP +import com.typedb.bazel.distribution.platform.jvm.Options.Keys.WINDOWS_WIX_TOOLSET_PATH import java.io.File import java.io.FileInputStream import java.util.Properties diff --git a/platform/jvm/ShellArgs.kt b/platform/jvm/ShellArgs.kt index eab141f0..b227c0e2 100644 --- a/platform/jvm/ShellArgs.kt +++ b/platform/jvm/ShellArgs.kt @@ -1,4 +1,4 @@ -package com.vaticle.bazel.distribution.platform.jvm +package com.typedb.bazel.distribution.platform.jvm object ShellArgs { object Programs { diff --git a/platform/jvm/rules.bzl b/platform/jvm/rules.bzl index 205e5c4d..2e0d98d9 100644 --- a/platform/jvm/rules.bzl +++ b/platform/jvm/rules.bzl @@ -17,7 +17,7 @@ # under the License. # -load("@vaticle_bazel_distribution//common:rules.bzl", _assemble_zip = "assemble_zip", _java_deps = "java_deps") +load("@typedb_bazel_distribution//common:rules.bzl", _assemble_zip = "assemble_zip", _java_deps = "java_deps") supported_oses = ["Mac", "Linux", "Windows"] @@ -296,7 +296,7 @@ _assemble_zip_to_jvm_platform = rule( doc = "Archive containing the Windows WiX toolset", ), "_assemble_jvm_platform_bin": attr.label( - default = "@vaticle_bazel_distribution//platform/jvm:assembler-bin", + default = "@typedb_bazel_distribution//platform/jvm:assembler-bin", executable = True, cfg = "host", ), @@ -311,11 +311,11 @@ _assemble_zip_to_jvm_platform = rule( def native_jdk17(): return select({ - "@vaticle_bazel_distribution//platform:is_linux_arm64": "@jdk17_linux_arm64//file", - "@vaticle_bazel_distribution//platform:is_linux_x86_64": "@jdk17_linux_x86_64//file", - "@vaticle_bazel_distribution//platform:is_mac_arm64": "@jdk17_mac_arm64//file", - "@vaticle_bazel_distribution//platform:is_mac_x86_64": "@jdk17_mac_x86_64//file", - "@vaticle_bazel_distribution//platform:is_windows_x86_64": "@jdk17_windows_x86_64//file", + "@typedb_bazel_distribution//platform:is_linux_arm64": "@jdk17_linux_arm64//file", + "@typedb_bazel_distribution//platform:is_linux_x86_64": "@jdk17_linux_x86_64//file", + "@typedb_bazel_distribution//platform:is_mac_arm64": "@jdk17_mac_arm64//file", + "@typedb_bazel_distribution//platform:is_mac_x86_64": "@jdk17_mac_x86_64//file", + "@typedb_bazel_distribution//platform:is_windows_x86_64": "@jdk17_windows_x86_64//file", }) def assemble_jvm_platform(name, @@ -370,9 +370,9 @@ def assemble_jvm_platform(name, main_class = main_class, jdk = jdk, os = select({ - "@vaticle_bazel_distribution//platform:is_mac": "Mac", - "@vaticle_bazel_distribution//platform:is_linux": "Linux", - "@vaticle_bazel_distribution//platform:is_windows": "Windows", + "@typedb_bazel_distribution//platform:is_mac": "Mac", + "@typedb_bazel_distribution//platform:is_linux": "Linux", + "@typedb_bazel_distribution//platform:is_windows": "Windows", }), verbose = verbose, log_sensitive_data = log_sensitive_data, @@ -382,13 +382,13 @@ def assemble_jvm_platform(name, mac_app_id = mac_app_id, mac_entitlements = mac_entitlements, mac_code_signing_cert = select({ - "@vaticle_bazel_distribution//platform/jvm:apple-code-sign": mac_code_signing_cert, + "@typedb_bazel_distribution//platform/jvm:apple-code-sign": mac_code_signing_cert, "//conditions:default": None, }), mac_deep_sign_jars_regex = mac_deep_sign_jars_regex, windows_menu_group = windows_menu_group, windows_wix_toolset = select({ - "@vaticle_bazel_distribution//platform:is_windows": windows_wix_toolset, + "@typedb_bazel_distribution//platform:is_windows": windows_wix_toolset, "//conditions:default": None, }), ) diff --git a/rpm/generate_spec_file.py b/rpm/generate_spec_file.py deleted file mode 100644 index 027bcaa6..00000000 --- a/rpm/generate_spec_file.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 - -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, 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. -# - -import argparse -import json -import re - -WORKSPACE_REF_PATTERN = re.compile(r'.*%{@(?P.*)}.*') - -parser = argparse.ArgumentParser() -parser.add_argument('--output', required=True, help='Output .spec file') -parser.add_argument('--spec_file', required=True, help='Input .spec file') -parser.add_argument('--workspace_refs', help='Optional file with workspace references') -args = parser.parse_args() - -workspace_refs = { - 'commits': {}, - 'tags': {} -} - -replacements = {} - -if args.workspace_refs: - with open(args.workspace_refs) as f: - workspace_refs = json.load(f) - -all_workspaces = set() - -for ws, commit in workspace_refs['commits'].items(): - replacements["%{{@{}}}".format(ws)] = '0.0.0_' + commit - all_workspaces.add(ws) - -for ws, tag in workspace_refs['tags'].items(): - replacements["%{{@{}}}".format(ws)] = tag - all_workspaces.add(ws) - -with open(args.spec_file) as spec, open(args.output, 'w') as output: - lines = spec.readlines() - for line in lines: - match = WORKSPACE_REF_PATTERN.match(line) - if match: - workspace_ref = match.group('workspace_ref') - if workspace_ref not in all_workspaces: - raise Exception('invalid workspace was referenced: `{}`; valid workspaces to reference are: {}'.format( - workspace_ref, list(all_workspaces) - )) - for replacement_key, replacement_value in replacements.items(): - line = line.replace(replacement_key, replacement_value) - output.write(line) diff --git a/rpm/rules.bzl b/rpm/rules.bzl deleted file mode 100644 index f7deaf4d..00000000 --- a/rpm/rules.bzl +++ /dev/null @@ -1,231 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, 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. -# - -load("@rules_pkg//:pkg.bzl", "pkg_tar") -load("@rules_pkg//:rpm.bzl", "pkg_rpm") - - -def _assemble_rpm_version_file_impl(ctx): - version = ctx.var.get('version', '0.0.0') - - if len(version) == 40: - # this is a commit SHA, most likely - version = "0.0.0_{}".format(version) - - ctx.actions.run_shell( - inputs = [], - outputs = [ctx.outputs.version_file], - command = "echo {} > {}".format(version, ctx.outputs.version_file.path) - ) - - -_assemble_rpm_version_file = rule( - outputs = { - "version_file": "%{name}.version" - }, - implementation = _assemble_rpm_version_file_impl -) - -def assemble_rpm(name, - package_name, - spec_file, - version_file = None, - workspace_refs = None, - installation_dir = None, - archives = [], - empty_dirs = [], - files = {}, - permissions = {}, - symlinks = {}, - tags = []): - """Assemble package for installation with RPM - - Args: - name: A unique name for this target. - package_name: Package name for built .rpm package - spec_file: The RPM spec file to use - version_file: File containing version number of a package. - Alternatively, pass --define version=VERSION to Bazel invocation. - Not specifying version defaults to '0.0.0' - workspace_refs: JSON file with other Bazel workspace references - installation_dir: directory into which .rpm package is unpacked at installation - archives: Bazel labels of archives that go into .rpm package - empty_dirs: list of empty directories created at package installation - files: mapping between Bazel labels of archives that go into .rpm package - and their resulting location on .rpm package installation - permissions: mapping between paths and UNIX permissions - symlinks: mapping between source and target of symbolic links - created at installation - tags: additional tags passed to all wrapped rules - """ - tag = "rpm_package_name={}".format(spec_file.split(':')[-1].replace('.spec', '')) - tar_name = "_{}-rpm-tar".format(package_name) - - rpm_data = [] - - if installation_dir: - pkg_tar( - name = tar_name, - extension = "tar.gz", - deps = archives, - package_dir = installation_dir, - empty_dirs = empty_dirs, - files = files, - mode = "0755", - symlinks = symlinks, - modes = permissions, - tags = tags, - ) - rpm_data.append(tar_name) - - if "osx_build" not in native.existing_rules(): - native.config_setting( - name = "osx_build", - constraint_values = [ - "@bazel_tools//platforms:osx", - "@bazel_tools//platforms:x86_64", - ] - ) - - if "linux_build" not in native.existing_rules(): - native.config_setting( - name = "linux_build", - constraint_values = [ - "@bazel_tools//platforms:linux", - "@bazel_tools//platforms:x86_64", - ], - tags = tags, - ) - - if workspace_refs: - modified_spec_target_name = name + "__spec_do_not_reference" - modified_spec_filename = name + '.spec' - args = [ - "$(location @vaticle_bazel_distribution//rpm:generate_spec_file)", - "--output", "$(location {})".format(modified_spec_filename), - "--spec_file", "$(location {})".format(spec_file), - "--workspace_refs", "$(location {})".format(workspace_refs), - ] - native.genrule( - name = modified_spec_target_name, - srcs = [spec_file, workspace_refs], - outs = [modified_spec_filename], - cmd = " ".join(args), - tools = ["@vaticle_bazel_distribution//rpm:generate_spec_file"], - tags = tags, - ) - spec_file = modified_spec_target_name - - if not version_file: - version_file = name + "__version__do_not_reference" - _assemble_rpm_version_file( - name = version_file - ) - - pkg_rpm( - name = "{}__do_not_reference__rpm".format(name), - architecture = "x86_64", - spec_file = spec_file, - version_file = version_file, - release = "1", - data = rpm_data, - rpmbuild_path = select({ - ":linux_build": "/usr/bin/rpmbuild", - ":osx_build": "/usr/local/bin/rpmbuild", - "//conditions:default": "" - }), - tags = tags, - ) - - native.genrule( - name = name, - srcs = ["{}__do_not_reference__rpm".format(name)], - cmd = "cp $$(echo $(SRCS) | awk '{print $$1}') $@", - outs = [package_name + ".rpm"], - tags = [tag] + tags, - ) - - -RpmInfo = provider( - fields = { - "package_name": "RPM package name" - } -) - -def _collect_rpm_package_name(target, ctx): - rpm_tag = ctx.rule.attr.tags[0] - package_name = rpm_tag.replace('rpm_package_name=', '') - return RpmInfo(package_name=package_name) - - -collect_rpm_package_name = aspect( - implementation = _collect_rpm_package_name -) - -def _deploy_rpm_impl(ctx): - ctx.actions.expand_template( - template = ctx.file._deployment_script, - output = ctx.outputs.deployment_script, - substitutions = { - "{RPM_PKG}": ctx.attr.target[RpmInfo].package_name, - "{snapshot}": ctx.attr.snapshot, - "{release}": ctx.attr.release, - }, - is_executable = True - ) - - symlinks = { - 'package.rpm': ctx.files.target[0], - } - - return DefaultInfo(executable = ctx.outputs.deployment_script, - runfiles = ctx.runfiles( - files=[ctx.files.target[0]], - symlinks = symlinks)) - - -deploy_rpm = rule( - attrs = { - "target": attr.label( - aspects = [collect_rpm_package_name], - doc = "`assemble_rpm` target to deploy" - ), - "snapshot": attr.string( - mandatory = True, - doc = "Remote repository to deploy rpm snapshot to" - ), - "release": attr.string( - mandatory = True, - doc = "Remote repository to deploy rpm release to" - ), - "_deployment_script": attr.label( - allow_single_file = True, - default = "//rpm/templates:deploy.py" - ), - }, - outputs = { - "deployment_script": "%{name}.py", - }, - implementation = _deploy_rpm_impl, - executable = True, - doc = """Deploy package built with `assemble_rpm` to RPM repository. - - Select deployment to `snapshot` or `release` repository with `bazel run //:some-deploy-rpm -- [snapshot|release] - """ -) diff --git a/rpm/templates/deploy.py b/rpm/templates/deploy.py deleted file mode 100644 index ea658801..00000000 --- a/rpm/templates/deploy.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 - -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, 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. -# - -import argparse -import os -import subprocess - - -rpm_pkg="{RPM_PKG}" - -parser = argparse.ArgumentParser() -parser.add_argument('repo_type') -args = parser.parse_args() - -repo_type_key = args.repo_type - -rpm_repositories = { - 'snapshot' : "{snapshot}", - 'release' : "{release}" -} - -rpm_registry = rpm_repositories[repo_type_key] - -rpm_username, rpm_password = ( - os.getenv('DEPLOY_RPM_USERNAME'), - os.getenv('DEPLOY_RPM_PASSWORD'), -) - -if not rpm_username: - raise Exception( - 'username should be passed via ' - '$DEPLOY_RPM_USERNAME env variable' - ) - -if not rpm_password: - raise Exception( - 'password should be passed via ' - '$DEPLOY_RPM_PASSWORD env variable' - ) - -package_name = '{}.rpm'.format( - subprocess.check_output([ - 'rpm', - '-qp', - 'package.rpm' -]).decode().strip()) - -upload_status_code = subprocess.check_output([ - 'curl', - '--silent', - '--output', '/dev/stderr', - '--write-out', '%{http_code}', - '-u', '{}:{}'.format(rpm_username, rpm_password), - '-X', 'PUT', - '--upload-file', 'package.rpm', - '{}/{}/{}'.format(rpm_registry, rpm_pkg, package_name) -]).decode().strip() - -if upload_status_code != '200': - raise Exception('upload failed, got HTTP status code {}'.format(upload_status_code)) - -print('Deployment completed.')