{"id":16474861,"url":"https://github.com/zegl/rules_codeowners","last_synced_at":"2025-10-19T19:59:14.276Z","repository":{"id":47636958,"uuid":"186680525","full_name":"zegl/rules_codeowners","owner":"zegl","description":"Bazel rules for generating CODEOWNERS from a workspace.","archived":false,"fork":false,"pushed_at":"2023-11-23T08:24:53.000Z","size":52,"stargazers_count":59,"open_issues_count":8,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-11T04:17:37.294Z","etag":null,"topics":["bazel","bazel-rules"],"latest_commit_sha":null,"homepage":"","language":"Starlark","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zegl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"polar":"zegl"}},"created_at":"2019-05-14T18:44:36.000Z","updated_at":"2024-12-02T00:42:57.000Z","dependencies_parsed_at":"2023-11-13T09:29:03.556Z","dependency_job_id":"d93306af-98e0-4a26-8ae4-6aef546f3e16","html_url":"https://github.com/zegl/rules_codeowners","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zegl%2Frules_codeowners","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zegl%2Frules_codeowners/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zegl%2Frules_codeowners/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zegl%2Frules_codeowners/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zegl","download_url":"https://codeload.github.com/zegl/rules_codeowners/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241131425,"owners_count":19914918,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","bazel-rules"],"created_at":"2024-10-11T12:34:41.737Z","updated_at":"2025-10-19T19:59:09.222Z","avatar_url":"https://github.com/zegl.png","language":"Starlark","funding_links":["https://polar.sh/zegl"],"categories":["Starlark"],"sub_categories":[],"readme":"# rules_codeowners\n\nUse Bazel to create GitHub CODEOWNERS.\n\nCODEOWNERS on GitHub is flawed in the way that there can only be one CODEOWNERS file.\n\n`rules_codeowners` allows you to define the CODEOWNERS at all levels in the repo, and then generating the final CODEOWNERs file.\n\n## Usage\n\n_See also: [README_DOCS.md](https://github.com/zegl/rules_codeowners/blob/master/README_DOCS.md)_\n\nrules_codeowners is available on the [Bazel Central Registry](https://registry.bazel.build/modules/rules_codeowners):\n\n**Add this to your `MODULE.bazel`:**\n\n```bzl\nbazel_dep(name = \"rules_codeowners\", version = \"0.2.1\")\n```\n\n**... or if you're not using modules, add this to `WORKSPACE`:**\n\n```bzl\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nRULES_CODEOWNERS_VERSION = \"de6749190dcc5209427799b1e9777f79ab623702\"\nRULES_CODEOWNERS_SHA = \"9277d41fefe2eded54ab1d3eeaebbef9ad28713291373a635079868980c6ead0\"\n\nhttp_archive(\n    name = \"rules_codeowners\",\n    strip_prefix = \"rules_codeowners-%s\" % RULES_CODEOWNERS_VERSION,\n    sha256 = RULES_CODEOWNERS_SHA,\n    url = \"https://github.com/zegl/rules_codeowners/archive/%s.zip\" % RULES_CODEOWNERS_VERSION,\n)\n```\n\n**In BUILD files:**\n\n```bzl\nload(\"@rules_codeowners//tools:codeowners.bzl\", \"codeowners\", \"generate_codeowners\")\n\n# Define one or many codeowners, should be added at multiple levels in the repo\ncodeowners(\n    name = \"team_rule\",\n\n    # Set either team or teams to assign the GitHub team ownership\n    team = \"@org/foo\",\n    # teams = [\"@org/team1\", \"@org/team2\"],\n\n    visibility = [\"//visibility:public\"],\n\n    # Optional rules below\n    pattern = \"*.js\", # Adds pattern to the end of the path if this rule label is\n                      # //foo/bar:codeowner, this would create an entry for /foo/bar/*.js\n\n    patterns = [\"*.js\", \"*.ts\"] # Same as pattern, but generates multiple rows, one for each pattern.\n                                # Only one of pattern and patterns can be set at the same time.\n)\n\n# The generate_codeowners rule ties together multiple codeowners (and generate_codeowners) rules, and\n# generates the final CODEOWNERS file.\n#\n# A generate_codeowners can use another generate_codeowners in the `owners` list,\n# to effectively delegate access to modify the CODOWNERS in a part of the code-tree.\ngenerate_codeowners(\n    name = \"generate_codeowners\",\n    owners = [\n        \":team_rule\",\n    ],\n)\n```\n\n\nThe `generate_codeowners` rule (`//:generate_codeowners`), can be built with Bazel to create\nthe complete CODEOWNERS file, the generated file will be located at `bazel-bin/generate_codeowners.out` by default.\n\n```bash\nbazel build //:generate_codeowners\n```\n\n## Making sure that the CODEOWNERS is up to date\n\nIt's not possible for Bazel to output files to the workspace, but it _is_ possible to compare the current CODEOWNERS\nwith the generated version, to remind you that it's out of date with a `sh_test`.\n\n\n```bzl\nsh_test(\n    name = \"validate_codeowoners_up_to_date\",\n    srcs = [\"@rules_codeowners//tools:diff.sh\"],\n    args = [\n        \"$(location :generate_codeowners.out)\",\n        \"$(location CODEOWNERS)\",\n    ],\n    data = [\n        \"CODEOWNERS\",\n        \":generate_codeowners.out\",\n    ],\n)\n```\n\n## Automation tip: Automatically populate the `generate_codeowners`\n\nTo automatically set all `codeowners` as owners in a `generate_codeowners`, the following script that utilizes `bazel query` and [`buildozer`](https://github.com/bazelbuild/buildtools/tree/master/buildozer) can be used.\n\n```bash\n#!/usr/bin/env bash\n\n# target to the generate_codeowners, eg \"//.github:gen_codeowners\"\nreadonly target=$1\n\nreadonly BAZEL=$(which bazel)\nreadonly BUILDOZER=$(which buildozer)\n\nreadonly new_owners=$(\n    # Query for all codeowners() rules (anchor at the front to avoid match on generate_codeowners rule)\n    $BAZEL query --output=label 'kind(\"^codeowners rule\", //...)' |\n    # Print the length of each label at the front of the line\n    awk '{ print length, $0 }' |\n    # Sort shortest-first, so that the root //:OWNERS ends up first in CODEOWNERS\n    sort -n -s |\n    # 43 label -\u003e \"label\"\n    awk '{ print \"\\x22\" $2 \"\\x22\" }' |\n    # comma-separated\n    tr '\\n' ','\n)\n\nreadonly command=\"set owners [${new_owners}]|${target}\"\n\necho \"$command\" | $BUILDOZER -f -\n```\n\n## Automation tip: Verify that all codeowners are transiently depended on a `generate_codeowners`\n\nTo verify that all `codeowners` are targeted by a `generate_codeowners`, a script like the one below can be used.\n\n```bash\n#!/usr/bin/env bash\n\n# target to the generate_codeowners, eg \"//.github:gen_codeowners\"\nreadonly target=$1\n\nreadonly TEEFILE=$(mktemp)\nreadonly BAZEL=$(which bazel)\n\n$BAZEL query \"kind(codeowners, //...) except deps(${target})\" 2\u003e\u00261 | tee \"$TEEFILE\" | grep \"Empty results\"\nEXIT=$?\n\nif [ \"$EXIT\" -eq 1 ]; then\n    cat \"$TEEFILE\"\n    echo \"--\u003e All codeowners rules must be depended on by ${target}\"\n    echo \"--\u003e Add the codeowners as a dependency, or delete the target\"\n    exit 1\nfi\n\nexit 0\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzegl%2Frules_codeowners","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzegl%2Frules_codeowners","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzegl%2Frules_codeowners/lists"}