Skip to content

Commit cf30052

Browse files
committed
Use GitHub App for codeowner validation and remove hacky script
We shouldn't use personal access tokens, instead we created a GitHub App with read-only access to just this repository. While codeowners-validator supports GitHub App authentication, the same cannot be said for the hacky script I wrote because there was no support for checking write access: mszostok/codeowners-validator#157 Instead of trying to hack the script more to make it work with GitHub App authentication, I decided to implement it into codeowners-validator itself: mszostok/codeowners-validator#222 Because it's not merged/released yet, we need to build it ourselves, so I added some Nix to do that reproducibly.
1 parent 9c1ee55 commit cf30052

File tree

7 files changed

+121
-78
lines changed

7 files changed

+121
-78
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,24 @@ jobs:
3131
with:
3232
path: trusted-base
3333

34+
- name: Build codeowners validator
35+
# We run the result of this with access to secrets later, so it's important to trust this!
36+
run: nix-build trusted-base -A packages.codeowners-validator
37+
3438
- uses: actions/checkout@v4
3539
with:
3640
ref: refs/pull/${{ github.event.pull_request.number }}/merge
3741
path: untrusted-pr
3842

39-
- uses: mszostok/[email protected]
40-
with:
41-
# GitHub access token is required only if the `owners` check is enabled
42-
# See https://github.com/mszostok/codeowners-validator/blob/main/docs/gh-auth.md#public-repositories
43-
github_access_token: "${{ secrets.OWNERS_VALIDATOR_GITHUB_SECRET }}"
44-
45-
# The repository path in which CODEOWNERS file should be validated."
46-
repository_path: untrusted-pr
47-
48-
# The owner and repository name. For example, gh-codeowners/codeowners-samples. Used to check if GitHub team is in the given organization and has permission to the given repository."
49-
owner_checker_repository: "${{ github.repository }}"
50-
51-
# "The comma-separated list of experimental checks that should be executed. By default, all experimental checks are turned off. Possible values: notowned,avoid-shadowing"
52-
experimental_checks: "notowned,avoid-shadowing"
53-
54-
# Specifies whether CODEOWNERS may have unowned files. For example, `/infra/oncall-rotator/oncall-config.yml` doesn't have owner and this is not reported.
55-
owner_checker_allow_unowned_patterns: "false"
56-
57-
# Specifies whether only teams are allowed as owners of files.
58-
owner_checker_owners_must_be_teams: "false"
59-
60-
# The above validator doesn't currently ensure that people have write access: https://github.com/mszostok/codeowners-validator/issues/157
61-
# So we're doing it manually instead
62-
- name: Check that codeowners have write access
63-
# Important that we run the script from the base branch,
64-
# because otherwise a PR from a fork could change it to extract the secret
65-
run: trusted-base/scripts/unprivileged-owners.sh untrusted-pr ${{ github.repository }}
43+
- name: Validate codeowners
44+
run: result/bin/codeowners-validator
6645
env:
67-
GH_TOKEN: "${{ secrets.OWNERS_VALIDATOR_GITHUB_SECRET }}"
46+
# See https://github.com/mszostok/codeowners-validator/blob/main/docs/gh-auth.md#public-repositories
47+
GITHUB_APP_ID: ${{ secrets.APP_ID }}
48+
GITHUB_APP_INSTALLATION_ID: ${{ secrets.APP_INSTALLATION_ID }}
49+
GITHUB_APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
50+
REPOSITORY_PATH: untrusted-pr
51+
OWNER_CHECKER_REPOSITORY: ${{ github.repository }}
52+
EXPERIMENTAL_CHECKS: "notowned,avoid-shadowing"
53+
OWNER_CHECKER_ALLOW_UNOWNED_PATTERNS: "false"
54+
OWNER_CHECKER_OWNERS_MUST_BE_TEAMS: "false"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
result*

default.nix

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
let
2+
sources = import ./npins;
3+
in
4+
{
5+
system ? builtins.currentSystem,
6+
nixpkgs ? sources.nixpkgs,
7+
}:
8+
let
9+
pkgs = import nixpkgs {
10+
inherit system;
11+
config = { };
12+
overlays = [ ];
13+
};
14+
inherit (pkgs) lib;
15+
16+
packages = {
17+
codeowners-validator = pkgs.buildGoModule {
18+
name = "codeowners-validator";
19+
src = sources.codeowners-validator;
20+
vendorHash = "sha256-R+pW3xcfpkTRqfS2ETVOwG8PZr0iH5ewroiF7u8hcYI=";
21+
postPatch = "rm -r docs/investigation";
22+
};
23+
};
24+
25+
in
26+
{
27+
inherit packages;
28+
29+
shell = pkgs.mkShell {
30+
packages = [
31+
pkgs.npins
32+
];
33+
};
34+
}

npins/default.nix

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Generated by npins. Do not modify; will be overwritten regularly
2+
let
3+
data = builtins.fromJSON (builtins.readFile ./sources.json);
4+
version = data.version;
5+
6+
mkSource = spec:
7+
assert spec ? type; let
8+
path =
9+
if spec.type == "Git" then mkGitSource spec
10+
else if spec.type == "GitRelease" then mkGitSource spec
11+
else if spec.type == "PyPi" then mkPyPiSource spec
12+
else if spec.type == "Channel" then mkChannelSource spec
13+
else builtins.throw "Unknown source type ${spec.type}";
14+
in
15+
spec // { outPath = path; };
16+
17+
mkGitSource = { repository, revision, url ? null, hash, ... }:
18+
assert repository ? type;
19+
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
20+
# In the latter case, there we will always be an url to the tarball
21+
if url != null then
22+
(builtins.fetchTarball {
23+
inherit url;
24+
sha256 = hash; # FIXME: check nix version & use SRI hashes
25+
})
26+
else assert repository.type == "Git"; builtins.fetchGit {
27+
url = repository.url;
28+
rev = revision;
29+
# hash = hash;
30+
};
31+
32+
mkPyPiSource = { url, hash, ... }:
33+
builtins.fetchurl {
34+
inherit url;
35+
sha256 = hash;
36+
};
37+
38+
mkChannelSource = { url, hash, ... }:
39+
builtins.fetchTarball {
40+
inherit url;
41+
sha256 = hash;
42+
};
43+
in
44+
if version == 3 then
45+
builtins.mapAttrs (_: mkSource) data.pins
46+
else
47+
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"

npins/sources.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"pins": {
3+
"codeowners-validator": {
4+
"type": "Git",
5+
"repository": {
6+
"type": "GitHub",
7+
"owner": "tweag",
8+
"repo": "codeowners-validator"
9+
},
10+
"branch": "simpler-faster-permission-check",
11+
"revision": "a69f70c0bd8ec168ff695f412afa83c7b7a65413",
12+
"url": "https://github.com/tweag/codeowners-validator/archive/a69f70c0bd8ec168ff695f412afa83c7b7a65413.tar.gz",
13+
"hash": "1rybdypjgn4i065r6msfwyx1rvv73x19p28lps3si79bwbkg2xg0"
14+
},
15+
"nixpkgs": {
16+
"type": "Channel",
17+
"name": "nixpkgs-unstable",
18+
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre616757.4c86138ce486/nixexprs.tar.xz",
19+
"hash": "0lbvdj9jc7g3pqs0yvahpb8y453gn65jvkvbnnkbi6m4afp92p04"
20+
}
21+
},
22+
"version": 3
23+
}

scripts/unprivileged-owners.sh

Lines changed: 0 additions & 50 deletions
This file was deleted.

shell.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(import ./. { }).shell

0 commit comments

Comments
 (0)