Skip to content

Commit

Permalink
chore: allow internal-release tags (#117)
Browse files Browse the repository at this point in the history
Add support for internal-release tags on ot3-firmware and oe-core.
Internal release tags on those repos are formatted as internal@version.
Builds that start from internal-release tags on the monorepo or here
will use internal-release tags from everything instead of release tags.
  • Loading branch information
sfoster1 authored Jan 3, 2024
1 parent e0741b6 commit 1d8d245
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/actions/build-refs/action/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ const VARIANT_TEST_SPECS: Array<[string, Ref, Variant]> = [
VARIANT_TEST_SPECS.forEach(
([testNameFragment, testMonorepoRef, testExpectedResult]) => {
test(`variant ${testNameFragment}`, () => {
expect(action.variantForRef(testMonorepoRef)).toStrictEqual(
expect(action.resolveBuildVariant(testMonorepoRef)).toStrictEqual(
testExpectedResult
)
})
Expand Down
86 changes: 54 additions & 32 deletions .github/actions/build-refs/action/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ export type BuildType = 'develop' | 'release'
export type Variant = 'internal-release' | 'release'
const orderedRepos: Repo[] = ['monorepo', 'oe-core', 'ot3-firmware']

export interface BuildDetails {
buildType: BuildType
buildVariant: Variant
}

export type Branch = string
export type Tag = string
export type Ref = Branch | Tag
Expand Down Expand Up @@ -35,27 +40,34 @@ export interface GitHubApiTag {
ref: Tag
}

export function variantForRef(ref: Ref): Variant {
export function resolveBuildVariant(ref: Ref): Variant {
if (ref.startsWith('refs/heads')) {
if (ref.includes('internal-release')) {
return 'internal-release'
} else {
return 'release'
}
} else if (ref.startsWith('refs/tags')) {
if (ref.includes('ot3@')) {
if (ref.includes('ot3@') || ref.includes('internal@')) {
return 'internal-release'
} else if (ref.startsWith('refs/tags/v')) {
return 'release'
}
}
return 'internal-release'
}
function latestTagPrefixFor(repo: Repo): string {
if (repo === 'monorepo') return 'refs/tags/v'
if (repo === 'oe-core') return 'refs/tags/v'
if (repo === 'ot3-firmware') return 'refs/tags/v'
throw new Error(`Unknown repo ${repo}`)

function latestTagPrefixFor(repo: Repo, variant: Variant): string[] {
if (variant === 'release') {
return ['refs/tags/v']
}
if (variant === 'internal-release') {
if (repo === 'monorepo') return ['refs/tags/internal@', 'refs/tags/ot3@v']
if (repo === 'oe-core') return ['refs/tags/internal@']
if (repo === 'ot3-firmware') return ['refs/tags/internal@']
throw new Error(`Unknown repo ${repo}`)
}
throw new Error(`Unknown variant ${variant}`)
}

export function latestTag(tagRefs: GitHubApiTag[]): Tag | null {
Expand Down Expand Up @@ -141,27 +153,40 @@ export function refsToAttempt(
)
}

async function resolveRefs(toAttempt: AttemptableRefs): Promise<OutputRefs> {
async function resolveRefs(
toAttempt: AttemptableRefs,
variant: Variant
): Promise<OutputRefs> {
const token = core.getInput('token')
let resolved = new Map()
for (const [repo, refList] of toAttempt) {
const octokit = getOctokit(token)

const fetchTags = async (repoName: Repo): Promise<Ref | null> => {
core.info(`finding latest tag for ${repoName}`)
return octokit.rest.git
.listMatchingRefs({
...restDetailsFor(repoName),
ref: restAPICompliantRef(latestTagPrefixFor(repoName)),
})
.then(response => {
if (response.status != 200) {
throw new Error(
`Bad response from github api for ${repoName} get tags: ${response.status}`
)
}
return latestTag(response.data)
})
return Promise.all(
latestTagPrefixFor(repoName, variant).map(prefix =>
octokit.rest.git
.listMatchingRefs({
...restDetailsFor(repoName),
ref: restAPICompliantRef(prefix),
})
.then(response => {
if (response.status != 200) {
throw new Error(
`Bad response from github api for ${repoName} get tags: ${response.status}`
)
}
const latest = latestTag(response.data)
core.debug(
`latest tag for ${repoName} variant ${variant} is ${latest}`
)
return latest
})
)
).then(results =>
results.reduce((prev, current) => prev ?? current, null)
)
}

// this is a big function to be inline and untestable, but tookit doesn't export
Expand Down Expand Up @@ -215,6 +240,11 @@ async function run() {
})
const [authoritative, isMain] = authoritativeRef(inputs)
core.debug(`authoritative ref is ${authoritative} (main: ${isMain})`)
const buildType = resolveBuildType(authoritative)
const buildVariant = resolveBuildVariant(authoritative)
core.info(`Resolved build type to ${buildType}`)
core.info(`Resolved build variant to ${buildVariant}`)

const attemptable = Array.from(inputs.entries()).reduce(
(prev: AttemptableRefs, [repoName, inputRef]): AttemptableRefs => {
return prev.set(
Expand All @@ -229,8 +259,10 @@ async function run() {
attemptable.forEach((refs, repo) => {
core.debug(`found attemptable refs for ${repo}: ${refs.join(', ')}`)
})
core.setOutput('build-type', buildType)
core.setOutput('variant', buildVariant)

const resolved = await resolveRefs(attemptable)
const resolved = await resolveRefs(attemptable, buildVariant)
resolved.forEach((ref, repo) => {
if (!ref) {
throw new Error(
Expand All @@ -239,16 +271,6 @@ async function run() {
}
core.info(`Resolved ${repo} to ${ref}`)
core.setOutput(repo, ref)

// Determine the build-type based on the monorepo ref
if (repo === 'monorepo') {
const buildType = resolveBuildType(ref)
const variant = variantForRef(ref)
core.info(`Resolved oe-core build-type to ${buildType}`)
core.setOutput('build-type', buildType)
core.setOutput('variant', variant)
core.info(`Resolved oe-core variant to ${variant}`)
}
})
}

Expand Down
57 changes: 31 additions & 26 deletions .github/actions/build-refs/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9728,7 +9728,7 @@ var __webpack_exports__ = {};
__nccwpck_require__.r(__webpack_exports__);
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
/* harmony export */ "restAPICompliantRef": () => (/* binding */ restAPICompliantRef),
/* harmony export */ "variantForRef": () => (/* binding */ variantForRef),
/* harmony export */ "resolveBuildVariant": () => (/* binding */ resolveBuildVariant),
/* harmony export */ "latestTag": () => (/* binding */ latestTag),
/* harmony export */ "authoritativeRef": () => (/* binding */ authoritativeRef),
/* harmony export */ "refsToAttempt": () => (/* binding */ refsToAttempt),
Expand Down Expand Up @@ -9760,7 +9760,7 @@ function mainRefFor(input) {
function restAPICompliantRef(input) {
return input.replace('refs/', '');
}
function variantForRef(ref) {
function resolveBuildVariant(ref) {
if (ref.startsWith('refs/heads')) {
if (ref.includes('internal-release')) {
return 'internal-release';
Expand All @@ -9770,7 +9770,7 @@ function variantForRef(ref) {
}
}
else if (ref.startsWith('refs/tags')) {
if (ref.includes('ot3@')) {
if (ref.includes('ot3@') || ref.includes('internal@')) {
return 'internal-release';
}
else if (ref.startsWith('refs/tags/v')) {
Expand All @@ -9779,14 +9779,20 @@ function variantForRef(ref) {
}
return 'internal-release';
}
function latestTagPrefixFor(repo) {
if (repo === 'monorepo')
return 'refs/tags/v';
if (repo === 'oe-core')
return 'refs/tags/v';
if (repo === 'ot3-firmware')
return 'refs/tags/v';
throw new Error(`Unknown repo ${repo}`);
function latestTagPrefixFor(repo, variant) {
if (variant === 'release') {
return ['refs/tags/v'];
}
if (variant === 'internal-release') {
if (repo === 'monorepo')
return ['refs/tags/internal@', 'refs/tags/ot3@v'];
if (repo === 'oe-core')
return ['refs/tags/internal@'];
if (repo === 'ot3-firmware')
return ['refs/tags/internal@'];
throw new Error(`Unknown repo ${repo}`);
}
throw new Error(`Unknown variant ${variant}`);
}
function latestTag(tagRefs) {
var _a, _b;
Expand Down Expand Up @@ -9842,22 +9848,24 @@ function refsToAttempt(requesterRef, requesterIsMain, requestedMain) {
// try.
return visitRefsByType(requesterRef, requesterBranch => branchesToAttempt(requesterBranch, requesterIsMain, requestedMain), requesterTag => tagsToAttempt(requesterTag, requestedMain));
}
function resolveRefs(toAttempt) {
function resolveRefs(toAttempt, variant) {
return __awaiter(this, void 0, void 0, function* () {
const token = _actions_core__WEBPACK_IMPORTED_MODULE_1__.getInput('token');
let resolved = new Map();
for (const [repo, refList] of toAttempt) {
const octokit = (0,_actions_github__WEBPACK_IMPORTED_MODULE_0__.getOctokit)(token);
const fetchTags = (repoName) => __awaiter(this, void 0, void 0, function* () {
_actions_core__WEBPACK_IMPORTED_MODULE_1__.info(`finding latest tag for ${repoName}`);
return octokit.rest.git
.listMatchingRefs(Object.assign(Object.assign({}, restDetailsFor(repoName)), { ref: restAPICompliantRef(latestTagPrefixFor(repoName)) }))
return Promise.all(latestTagPrefixFor(repoName, variant).map(prefix => octokit.rest.git
.listMatchingRefs(Object.assign(Object.assign({}, restDetailsFor(repoName)), { ref: restAPICompliantRef(prefix) }))
.then(response => {
if (response.status != 200) {
throw new Error(`Bad response from github api for ${repoName} get tags: ${response.status}`);
}
return latestTag(response.data);
});
const latest = latestTag(response.data);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.debug(`latest tag for ${repoName} variant ${variant} is ${latest}`);
return latest;
}))).then(results => results.reduce((prev, current) => prev !== null && prev !== void 0 ? prev : current, null));
});
// this is a big function to be inline and untestable, but tookit doesn't export
// the type for the octokit object above so what are you gonna do
Expand Down Expand Up @@ -9895,6 +9903,10 @@ function run() {
});
const [authoritative, isMain] = authoritativeRef(inputs);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.debug(`authoritative ref is ${authoritative} (main: ${isMain})`);
const buildType = resolveBuildType(authoritative);
const buildVariant = resolveBuildVariant(authoritative);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.info(`Resolved build type to ${buildType}`);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.info(`Resolved build variant to ${buildVariant}`);
const attemptable = Array.from(inputs.entries()).reduce((prev, [repoName, inputRef]) => {
return prev.set(repoName, inputRef
? [inputRef]
Expand All @@ -9903,22 +9915,15 @@ function run() {
attemptable.forEach((refs, repo) => {
_actions_core__WEBPACK_IMPORTED_MODULE_1__.debug(`found attemptable refs for ${repo}: ${refs.join(', ')}`);
});
const resolved = yield resolveRefs(attemptable);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.setOutput('build-type', buildType);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.setOutput('variant', buildVariant);
const resolved = yield resolveRefs(attemptable, buildVariant);
resolved.forEach((ref, repo) => {
if (!ref) {
throw new Error(`Could not resolve ${repo} input reference ${inputs.get(repo)}`);
}
_actions_core__WEBPACK_IMPORTED_MODULE_1__.info(`Resolved ${repo} to ${ref}`);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.setOutput(repo, ref);
// Determine the build-type based on the monorepo ref
if (repo === 'monorepo') {
const buildType = resolveBuildType(ref);
const variant = variantForRef(ref);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.info(`Resolved oe-core build-type to ${buildType}`);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.setOutput('build-type', buildType);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.setOutput('variant', variant);
_actions_core__WEBPACK_IMPORTED_MODULE_1__.info(`Resolved oe-core variant to ${variant}`);
}
});
});
}
Expand Down

0 comments on commit 1d8d245

Please sign in to comment.