Skip to content

Commit a647c9f

Browse files
authored
Merge branch 'main' into simonfaltum/doctor-command
2 parents 487b63f + 2705046 commit a647c9f

File tree

305 files changed

+5163
-1664
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

305 files changed

+5163
-1664
lines changed

.github/CODEOWNERS

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

.github/OWNERS

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Maintainers (can approve any PR)
2-
* @andrewnester @anton-107 @denik @pietern @shreyas-goenka @simonfaltum
2+
* @andrewnester @anton-107 @denik @pietern @shreyas-goenka @simonfaltum @renaudhartert-db
33

44
# Bundles
5-
/bundle/ @andrewnester @anton-107 @denik @pietern @shreyas-goenka @lennartkats-db
6-
/cmd/bundle/ @andrewnester @anton-107 @denik @pietern @shreyas-goenka @lennartkats-db
7-
/acceptance/bundle/ @andrewnester @anton-107 @denik @pietern @shreyas-goenka @lennartkats-db
8-
/libs/template/ @andrewnester @anton-107 @denik @pietern @shreyas-goenka @simonfaltum @lennartkats-db
5+
/bundle/ team:bundle @lennartkats-db
6+
/cmd/bundle/ team:bundle @lennartkats-db
7+
/acceptance/bundle/ team:bundle @lennartkats-db
8+
/libs/template/ team:bundle @lennartkats-db
99

1010
# Pipelines
1111
/cmd/pipelines/ @jefferycheng1 @kanterov @lennartkats-db
@@ -16,10 +16,48 @@
1616
/acceptance/labs/ @alexott @nfx
1717

1818
# Apps
19-
/cmd/apps/ @databricks/eng-apps-devex
20-
/cmd/workspace/apps/ @databricks/eng-apps-devex
21-
/libs/apps/ @databricks/eng-apps-devex
22-
/acceptance/apps/ @databricks/eng-apps-devex
19+
/cmd/apps/ team:eng-apps-devex
20+
/cmd/workspace/apps/ team:eng-apps-devex
21+
/libs/apps/ team:eng-apps-devex
22+
/acceptance/apps/ team:eng-apps-devex
23+
24+
# Auth
25+
/cmd/auth/ team:platform
26+
/libs/auth/ team:platform
27+
/acceptance/auth/ team:platform
28+
29+
# Filesystem & sync
30+
/cmd/fs/ team:platform
31+
/cmd/sync/ team:platform
32+
/libs/filer/ team:platform
33+
/libs/sync/ team:platform
34+
35+
# Core CLI infrastructure
36+
/cmd/root/ team:platform
37+
/cmd/version/ team:platform
38+
/cmd/completion/ team:platform
39+
/cmd/configure/ team:platform
40+
/cmd/cache/ team:platform
41+
/cmd/api/ team:platform
42+
/cmd/selftest/ team:platform
43+
/cmd/psql/ team:platform
44+
/libs/psql/ team:platform
45+
46+
# Libs (general)
47+
/libs/databrickscfg/ team:platform
48+
/libs/env/ team:platform
49+
/libs/flags/ team:platform
50+
/libs/cmdio/ team:platform
51+
/libs/log/ team:platform
52+
/libs/telemetry/ team:platform
53+
/libs/process/ team:platform
54+
/libs/git/ team:platform
55+
56+
# Integration tests
57+
/integration/ team:platform
58+
59+
# Internal
60+
/internal/ team:platform
2361

2462
# Experimental
25-
/experimental/aitools/ @databricks/eng-apps-devex @lennartkats-db
63+
/experimental/aitools/ team:eng-apps-devex @lennartkats-db

.github/OWNERTEAMS

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Team aliases for OWNERS file.
2+
# Use "team:<name>" in OWNERS to reference a team defined here.
3+
# Format: team:<name> @member1 @member2 ...
4+
#
5+
# Keep these in sync with actual GitHub team rosters. GITHUB_TOKEN can't
6+
# resolve org team membership via the API, so this file is the source of
7+
# truth for the maintainer-approval workflow.
8+
#
9+
# GitHub team pages:
10+
# bundle: https://github.com/orgs/databricks/teams/cli-maintainers
11+
# platform: https://github.com/orgs/databricks/teams/cli-platform
12+
# eng-apps-devex: https://github.com/orgs/databricks/teams/eng-apps-devex
13+
14+
team:bundle @andrewnester @anton-107 @denik @janniklasrose @pietern @shreyas-goenka
15+
team:platform @simonfaltum @renaudhartert-db @hectorcast-db @parthban-db @tanmay-db @Divyansh-db @tejaskochar-db @mihaimitrea-db @chrisst @rauchy
16+
team:eng-apps-devex @fjakobs @jamesbroadhead @Shridhad @atilafassina @keugenek @arsenyinfo @igrekun @pkosiec @MarioCadenas @pffigueiredo @ditadi @calvarjorge

.github/actions/setup-build-environment/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ runs:
2020
shell: bash
2121

2222
- name: Setup Go
23-
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
23+
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
2424
with:
2525
go-version-file: go.mod
2626
cache-dependency-path: |

.github/scripts/owners.js

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,56 @@
11
const fs = require("fs");
2+
const path = require("path");
3+
4+
/**
5+
* Read a file and return non-empty, non-comment lines split by whitespace.
6+
* Returns [] if the file does not exist.
7+
*
8+
* @param {string} filePath
9+
* @returns {string[][]} array of whitespace-split tokens per line
10+
*/
11+
function readDataLines(filePath) {
12+
let content;
13+
try {
14+
content = fs.readFileSync(filePath, "utf-8");
15+
} catch (e) {
16+
if (e.code === "ENOENT") return [];
17+
throw e;
18+
}
19+
const result = [];
20+
for (const raw of content.split("\n")) {
21+
const line = raw.trim();
22+
if (!line || line.startsWith("#")) continue;
23+
const parts = line.split(/\s+/);
24+
if (parts.length >= 2) result.push(parts);
25+
}
26+
return result;
27+
}
28+
29+
/**
30+
* Parse an OWNERTEAMS file into a map of team aliases.
31+
* Format: "team:<name> @member1 @member2 ..."
32+
* Returns Map<string, string[]> where key is "team:<name>" and value is member logins.
33+
*
34+
* @param {string} filePath - absolute path to the OWNERTEAMS file
35+
* @returns {Map<string, string[]>}
36+
*/
37+
function parseOwnerTeams(filePath) {
38+
const teams = new Map();
39+
for (const parts of readDataLines(filePath)) {
40+
if (!parts[0].startsWith("team:")) continue;
41+
const members = parts.slice(1).filter((p) => p.startsWith("@")).map((p) => p.slice(1));
42+
teams.set(parts[0], members);
43+
}
44+
return teams;
45+
}
246

347
/**
448
* Parse an OWNERS file (same format as CODEOWNERS).
549
* Returns array of { pattern, owners } rules.
650
*
51+
* If an OWNERTEAMS file exists alongside the OWNERS file, "team:<name>"
52+
* tokens are expanded to their member lists.
53+
*
754
* By default, team refs (org/team) are filtered out and @ is stripped.
855
* Pass { includeTeams: true } to keep team refs (with @ stripped).
956
*
@@ -13,18 +60,19 @@ const fs = require("fs");
1360
*/
1461
function parseOwnersFile(filePath, opts) {
1562
const includeTeams = opts && opts.includeTeams;
16-
const lines = fs.readFileSync(filePath, "utf-8").split("\n");
63+
const teamsPath = path.join(path.dirname(filePath), "OWNERTEAMS");
64+
const teams = parseOwnerTeams(teamsPath);
1765
const rules = [];
18-
for (const raw of lines) {
19-
const line = raw.trim();
20-
if (!line || line.startsWith("#")) continue;
21-
const parts = line.split(/\s+/);
22-
if (parts.length < 2) continue;
66+
for (const parts of readDataLines(filePath)) {
2367
const pattern = parts[0];
24-
const owners = parts
25-
.slice(1)
26-
.filter((p) => p.startsWith("@") && (includeTeams || !p.includes("/")))
27-
.map((p) => p.slice(1));
68+
const owners = [];
69+
for (const p of parts.slice(1)) {
70+
if (p.startsWith("team:") && teams.has(p)) {
71+
owners.push(...teams.get(p));
72+
} else if (p.startsWith("@") && (includeTeams || !p.includes("/"))) {
73+
owners.push(p.slice(1));
74+
}
75+
}
2876
rules.push({ pattern, owners });
2977
}
3078
return rules;
@@ -89,4 +137,4 @@ function getOwnershipGroups(filenames, rules) {
89137
return groups;
90138
}
91139

92-
module.exports = { parseOwnersFile, ownersMatch, findOwners, getMaintainers, getOwnershipGroups };
140+
module.exports = { parseOwnerTeams, parseOwnersFile, ownersMatch, findOwners, getMaintainers, getOwnershipGroups };

.github/scripts/owners.test.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const os = require("os");
55
const path = require("path");
66

77
const {
8+
parseOwnerTeams,
89
ownersMatch,
910
parseOwnersFile,
1011
findOwners,
@@ -125,6 +126,99 @@ describe("parseOwnersFile", () => {
125126
});
126127
});
127128

129+
// --- parseOwnerTeams ---
130+
131+
describe("parseOwnerTeams", () => {
132+
let tmpDir;
133+
134+
before(() => {
135+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "ownerteams-test-"));
136+
});
137+
138+
after(() => {
139+
fs.rmSync(tmpDir, { recursive: true });
140+
});
141+
142+
it("parses team definitions", () => {
143+
const teamsPath = path.join(tmpDir, "OWNERTEAMS");
144+
fs.writeFileSync(teamsPath, "team:platform @alice @bob @carol\n");
145+
const teams = parseOwnerTeams(teamsPath);
146+
assert.equal(teams.size, 1);
147+
assert.deepEqual(teams.get("team:platform"), ["alice", "bob", "carol"]);
148+
});
149+
150+
it("parses multiple teams", () => {
151+
const teamsPath = path.join(tmpDir, "OWNERTEAMS");
152+
fs.writeFileSync(teamsPath, "team:platform @alice @bob\nteam:bundle @carol @dave\n");
153+
const teams = parseOwnerTeams(teamsPath);
154+
assert.equal(teams.size, 2);
155+
assert.deepEqual(teams.get("team:platform"), ["alice", "bob"]);
156+
assert.deepEqual(teams.get("team:bundle"), ["carol", "dave"]);
157+
});
158+
159+
it("skips comments and blank lines", () => {
160+
const teamsPath = path.join(tmpDir, "OWNERTEAMS");
161+
fs.writeFileSync(teamsPath, "# comment\n\nteam:platform @alice\n");
162+
const teams = parseOwnerTeams(teamsPath);
163+
assert.equal(teams.size, 1);
164+
});
165+
166+
it("returns empty map if file does not exist", () => {
167+
const teams = parseOwnerTeams(path.join(tmpDir, "NONEXISTENT"));
168+
assert.equal(teams.size, 0);
169+
});
170+
});
171+
172+
// --- parseOwnersFile with team aliases ---
173+
174+
describe("parseOwnersFile with OWNERTEAMS", () => {
175+
let tmpDir;
176+
let ownersPath;
177+
let teamsPath;
178+
179+
before(() => {
180+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "owners-teams-test-"));
181+
ownersPath = path.join(tmpDir, "OWNERS");
182+
teamsPath = path.join(tmpDir, "OWNERTEAMS");
183+
});
184+
185+
after(() => {
186+
fs.rmSync(tmpDir, { recursive: true });
187+
});
188+
189+
it("expands team aliases to members", () => {
190+
fs.writeFileSync(teamsPath, "team:platform @alice @bob\n");
191+
fs.writeFileSync(ownersPath, "/cmd/auth/ team:platform\n");
192+
const rules = parseOwnersFile(ownersPath);
193+
assert.equal(rules.length, 1);
194+
assert.deepEqual(rules[0].owners, ["alice", "bob"]);
195+
});
196+
197+
it("mixes team aliases with individual owners", () => {
198+
fs.writeFileSync(teamsPath, "team:platform @alice @bob\n");
199+
fs.writeFileSync(ownersPath, "/cmd/auth/ team:platform @carol\n");
200+
const rules = parseOwnersFile(ownersPath);
201+
assert.equal(rules.length, 1);
202+
assert.deepEqual(rules[0].owners, ["alice", "bob", "carol"]);
203+
});
204+
205+
it("unknown team alias is ignored", () => {
206+
fs.writeFileSync(teamsPath, "team:platform @alice\n");
207+
fs.writeFileSync(ownersPath, "/cmd/auth/ team:unknown @bob\n");
208+
const rules = parseOwnersFile(ownersPath);
209+
assert.deepEqual(rules[0].owners, ["bob"]);
210+
});
211+
212+
it("works without OWNERTEAMS file", () => {
213+
const tmpDir2 = fs.mkdtempSync(path.join(os.tmpdir(), "owners-noteams-"));
214+
const ownersPath2 = path.join(tmpDir2, "OWNERS");
215+
fs.writeFileSync(ownersPath2, "* @alice\n");
216+
const rules = parseOwnersFile(ownersPath2);
217+
assert.deepEqual(rules[0].owners, ["alice"]);
218+
fs.rmSync(tmpDir2, { recursive: true });
219+
});
220+
});
221+
128222
// --- findOwners ---
129223

130224
describe("findOwners", () => {

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
steps:
2222
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2323

24-
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
24+
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
2525
with:
2626
go-version-file: go.mod
2727
# Use different schema from regular job, to avoid overwriting the same key

0 commit comments

Comments
 (0)