Skip to main content
Glama
artifact.bzl10.1 kB
load("@prelude//python:toolchain.bzl", "PythonToolchainInfo") load("//artifact:toolchain.bzl", "ArtifactToolchainInfo") """ Artifact publishing and promotion rules. # Platform Targets The platform_targets attribute declares which OS/architecture combinations should be built for an artifact. Valid platform strings: - `darwin-aarch64` - `darwin-x86_64` - `linux-aarch64` - `linux-x86_64` - `windows-x86_64` # Example usage in macros ```bzl deno_binary_artifact( name = "my-tool", binary = ":my-tool", platform_targets = ["linux-x86_64", "darwin-x86_64"], # Custom platforms skip_all_publish = False, # Default: allow publishing skip_all_promote = True, # Skip promotion to stable ) ``` # CI Integration CI systems query platform_targets to determine which platforms to build: ```sh buck2 uquery //bin/my-tool:publish-binary \ --output-attribute platform_targets \ --output-attribute skip_all \ --json ``` The promote rule uses platform_targets internally to generate `--target` args. """ # Valid platform strings # # Please keep list sorted VALID_PLATFORM_TARGETS = [ "darwin-aarch64", "darwin-x86_64", "linux-aarch64", "linux-x86_64", "windows-x86_64", ] # Valid Rust platform target strings. # # TODO(fnichol): remove when cross-compilation is supported, then use list above # # Please keep list sorted VALID_LINUX_PLATFORM_TARGETS = [ "linux-aarch64", "linux-x86_64", ] def validate_platform_targets(platform_targets: list[str], err_prefix: str) -> None: """Validate platform_targets list contains only valid platform strings. Args: platform_targets: List of platform strings to validate err_prefix: Description of where this validation is happening (for error messages) """ _validate_platform_targets_from_list(platform_targets, VALID_PLATFORM_TARGETS, err_prefix) # TODO(fnichol): remove when cross-compilation is supported, then use list above def validate_linux_platform_targets(platform_targets: list[str], err_prefix: str) -> None: """Validate platform_targets list contains only valid Rust platform strings. Args: platform_targets: List of platform strings to validate err_prefix: Description of where this validation is happening (for error messages) """ _validate_platform_targets_from_list(platform_targets, VALID_LINUX_PLATFORM_TARGETS, err_prefix) def _validate_platform_targets_from_list( platform_targets: list[str], valid_platform_targets: list[str], err_prefix: str) -> None: """Validate platform_targets list contains only valid platform strings. Args: platform_targets: List of platform strings to validate valid_platform_targets: List of all valid platform strings err_prefix: Description of where this validation is happening (for error messages) """ if not platform_targets: fail("{}: platform_targets cannot be empty".format(err_prefix)) for target in platform_targets: if target not in valid_platform_targets: fail( "{}: invalid platform '{}'. Supported platforms: {}".format( err_prefix, target, ", ".join(valid_platform_targets), ), ) ArtifactInfo = provider(fields = { "artifact": provider_field(typing.Any, default = None), "metadata": provider_field(typing.Any, default = None), "family": str, "variant": str, }) def artifact_publish_impl(ctx: AnalysisContext) -> list[[DefaultInfo, RunInfo]]: cli_args = ctx.actions.declare_output("args.txt") artifact_toolchain = ctx.attrs._artifact_toolchain[ArtifactToolchainInfo] cmd = cmd_args( ctx.attrs._python_toolchain[PythonToolchainInfo].interpreter, artifact_toolchain.publish[DefaultInfo].default_outputs, "--destination", ctx.attrs.destination, "--artifact-file", ctx.attrs.artifact[ArtifactInfo].artifact, "--metadata-file", ctx.attrs.artifact[ArtifactInfo].metadata, ) if ctx.attrs.cname: cmd.add("--cname") cmd.add(ctx.attrs.cname) ctx.actions.write(cli_args.as_output(), cmd) return [ DefaultInfo(default_output = cli_args), RunInfo(args = cmd), ] artifact_publish = rule( impl = artifact_publish_impl, attrs = { "destination": attrs.string( doc = """Destination [examples: {}].""".format(", ".join([ "s3://my-bucket", "gcs://bucket-name", "docker://docker.io", ])), ), "artifact": attrs.dep( providers = [ArtifactInfo], doc = """The `artifact` to publish.""", ), "cname": attrs.option( attrs.string(), default = None, doc = """Hostname used when calculating canonical URLs.""", ), "platform_targets": attrs.list( attrs.string(), default = [], doc = """List of target platforms (e.g., ["linux-x86_64", "darwin-x86_64"]). Used by CI to determine which platforms to build.""", ), "skip_all": attrs.bool( default = False, doc = """Skip publishing this artifact entirely. Useful for temporarily disabling artifact publication.""", ), "_python_toolchain": attrs.toolchain_dep( default = "toolchains//:python", providers = [PythonToolchainInfo], ), "_artifact_toolchain": attrs.toolchain_dep( default = "toolchains//:artifact", providers = [ArtifactToolchainInfo], ), }, ) def artifact_promote_impl(ctx: AnalysisContext) -> list[[DefaultInfo, RunInfo]]: cli_args = ctx.actions.declare_output("args.txt") artifact_toolchain = ctx.attrs._artifact_toolchain[ArtifactToolchainInfo] cmd = cmd_args( ctx.attrs._python_toolchain[PythonToolchainInfo].interpreter, artifact_toolchain.promote[DefaultInfo].default_outputs, "--destination", ctx.attrs.destination, "--channel", ctx.attrs.channel, "--family", ctx.attrs.family, "--variant", ctx.attrs.variant, ) if ctx.attrs.organization: cmd.add("--organization") cmd.add(ctx.attrs.organization) if ctx.attrs.cname: cmd.add("--cname") cmd.add(ctx.attrs.cname) for target in ctx.attrs.platform_targets: cmd.add("--target") cmd.add(target) ctx.actions.write(cli_args.as_output(), cmd) return [ DefaultInfo(default_output = cli_args), RunInfo(args = cmd), ] artifact_promote = rule( impl = artifact_promote_impl, attrs = { "destination": attrs.string( doc = """Destination [examples: {}].""".format(", ".join([ "s3://my-bucket", "gcs://bucket-name", "docker://docker.io", ])), ), "channel": attrs.string( doc = """Release channel.""", default = "stable", ), "family": attrs.string( doc = """Artifact family.""", ), "variant": attrs.string( doc = """Artifact variant.""", ), "cname": attrs.option( attrs.string(), default = None, doc = """Hostname used when calculating canonical URLs.""", ), "organization": attrs.option( attrs.string(), default = None, doc = """Artifact's organization.""", ), "platform_targets": attrs.list( attrs.string(), default = [], doc = """List of target platforms (e.g., ["linux-x86_64", "darwin-x86_64"]). Used to generate --target args for promote.py.""", ), "skip_all": attrs.bool( default = False, doc = """Skip promoting this artifact entirely. Useful for temporarily disabling artifact promotion.""", ), "_python_toolchain": attrs.toolchain_dep( default = "toolchains//:python", providers = [PythonToolchainInfo], ), "_artifact_toolchain": attrs.toolchain_dep( default = "toolchains//:artifact", providers = [ArtifactToolchainInfo], ), }, ) def artifact_download_impl(ctx: AnalysisContext) -> list[Provider]: """Download an artifact from S3 without extraction.""" # Construct S3 URL filename = "{}-{}-{}-{}.tar.gz".format( ctx.attrs.family, ctx.attrs.version, ctx.attrs.os, ctx.attrs.arch, ) url = "{}/{}/{}/{}/{}/{}".format( ctx.attrs.destination.rstrip("/"), ctx.attrs.family, ctx.attrs.version, ctx.attrs.os, ctx.attrs.arch, filename, ) # Download file output_file = ctx.actions.declare_output("{}-{}-{}-{}.tar.gz".format( ctx.attrs.family, ctx.attrs.version, ctx.attrs.os, ctx.attrs.arch, )) ctx.actions.download_file(output_file.as_output(), url, sha256 = ctx.attrs.sha256) return [DefaultInfo(default_output = output_file)] artifact_download = rule( impl = artifact_download_impl, attrs = { "destination": attrs.string( doc = """Destination base URL (e.g., https://artifacts.systeminit.com/toolchains).""", default = "https://artifacts.systeminit.com/toolchains", ), "family": attrs.string( doc = """Artifact family (rust, python, clang, deno).""", ), "version": attrs.string( doc = """Artifact version.""", ), "os": attrs.string( doc = """Operating system (linux, darwin).""", ), "arch": attrs.string( doc = """Architecture (x86_64, aarch64).""", ), "sha256": attrs.string( doc = """SHA256 checksum.""", ), }, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server