Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dev/release/src/campaigns.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CreatedChangeset } from './github'
import { readLine } from './util'
import { readLine, cacheFolder } from './util'
import YAML from 'yaml'
import execa from 'execa'
import fetch from 'node-fetch'
Expand All @@ -21,7 +21,7 @@ export async function sourcegraphCLIConfig(): Promise<SourcegraphCLIConfig> {
await commandExists('src') // CLI must be present for campaigns interactions
return {
SRC_ENDPOINT: DEFAULT_SRC_ENDPOINT,
SRC_ACCESS_TOKEN: await readLine('k8s.sgdev.org src-cli token: ', '.secrets/src-cli.txt'),
SRC_ACCESS_TOKEN: await readLine('k8s.sgdev.org src-cli token: ', `${cacheFolder}/src-cli.txt`),
}
}

Expand Down
31 changes: 20 additions & 11 deletions dev/release/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readLine, getWeekNumber } from './util'
import { cacheFolder, readLine, getWeekNumber } from './util'
import * as semver from 'semver'
import { readFileSync } from 'fs'
import { readFileSync, unlinkSync } from 'fs'
import { parse as parseJSONC } from '@sqs/jsonc-parser'

/**
Expand Down Expand Up @@ -29,11 +29,16 @@ export interface Config {
}
}

/**
* Default path of JSONC containing release configuration.
*/
const configPath = 'release-config.jsonc'

/**
* Loads configuration from predefined path. It does not do any special validation.
*/
export function loadConfig(): Config {
return parseJSONC(readFileSync('release-config.jsonc').toString()) as Config
return parseJSONC(readFileSync(configPath).toString()) as Config
}

/**
Expand All @@ -60,19 +65,23 @@ export async function releaseVersions(
// Verify the configured upcoming release. The response is cached and expires in a
// week, after which the captain is required to confirm again.
const now = new Date()
const cachedVersion = `.secrets/current_release_${now.getUTCFullYear()}_${getWeekNumber(now)}.txt`
const cachedVersionResponse = `${cacheFolder}/current_release_${now.getUTCFullYear()}_${getWeekNumber(now)}.txt`
const confirmVersion = await readLine(
`Please confirm the upcoming release version (configured: '${config.upcomingRelease}'): `,
cachedVersion
`Please confirm the upcoming release version configured in '${configPath}' (currently '${config.upcomingRelease}'): `,
cachedVersionResponse
)
const parsedConfirmed = semver.parse(confirmVersion, parseOptions)
let error = ''
if (!parsedConfirmed) {
throw new Error(`Provided version '${confirmVersion}' is not valid semver (in ${cachedVersion})`)
error = `Provided version '${confirmVersion}' is not valid semver`
} else if (semver.neq(parsedConfirmed, parsedUpcoming)) {
error = `Provided version '${confirmVersion}' and config.upcomingRelease '${config.upcomingRelease}' do not match - please update the release configuration at '${configPath}' and try again`
}
if (semver.neq(parsedConfirmed, parsedUpcoming)) {
throw new Error(
`Provided version '${confirmVersion}' and config.upcomingRelease '${config.upcomingRelease}' to not match - please update the release configuration, or confirm the version in your cached answer (in ${cachedVersion})`
)

// If error, abort and remove the cached response (since it is invalid anyway)
if (error !== '') {
unlinkSync(cachedVersionResponse)
throw new Error(error)
}

const versions = {
Expand Down
4 changes: 2 additions & 2 deletions dev/release/src/github.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Octokit from '@octokit/rest'
import { readLine, formatDate, timezoneLink } from './util'
import { readLine, formatDate, timezoneLink, cacheFolder } from './util'
import { promisify } from 'util'
import * as semver from 'semver'
import { mkdtemp as original_mkdtemp } from 'fs'
Expand All @@ -12,7 +12,7 @@ const mkdtemp = promisify(original_mkdtemp)
export async function getAuthenticatedGitHubClient(): Promise<Octokit> {
const githubPAT = await readLine(
'Enter a GitHub personal access token with "repo" scope (https://github.com/settings/tokens/new): ',
'.secrets/github.txt'
`${cacheFolder}/github.txt`
)
const trimmedGithubPAT = githubPAT.trim()
return new Octokit({ auth: trimmedGithubPAT })
Expand Down
6 changes: 3 additions & 3 deletions dev/release/src/google-calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import { google, calendar_v3 } from 'googleapis'
import { OAuth2Client } from 'googleapis-common'
import open from 'open'
import { Credentials } from 'google-auth-library'
import { readLine } from './util'
import { readLine, cacheFolder } from './util'
import { readFile, writeFile } from 'mz/fs'

const SCOPES = ['https://www.googleapis.com/auth/calendar.events']
const TOKEN_PATH = '.secrets/google-calendar-token.json'
const TOKEN_PATH = `${cacheFolder}/google-calendar-token.json`

export async function getClient(): Promise<OAuth2Client> {
const credentials = JSON.parse(
await readLine(
'Paste Google Calendar credentials (1Password "Release automation Google Calendar API App credentials"): ',
'.secrets/google-calendar-credentials.json'
`${cacheFolder}/google-calendar-credentials.json`
)
)
const { client_secret, client_id, redirect_uris } = credentials.installed
Expand Down
17 changes: 13 additions & 4 deletions dev/release/src/release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import {
import * as changelog from './changelog'
import * as campaigns from './campaigns'
import { Config, releaseVersions } from './config'
import { formatDate, timezoneLink } from './util'
import { cacheFolder, formatDate, timezoneLink } from './util'
import { addMinutes, isWeekend, eachDayOfInterval, addDays, subDays } from 'date-fns'
import { readFileSync, writeFileSync } from 'fs'
import { readFileSync, rmdirSync, writeFileSync } from 'fs'
import * as path from 'path'
import commandExists from 'command-exists'

Expand All @@ -36,6 +36,8 @@ export type StepID =
| 'release:add-to-campaign'
| 'release:finalize'
| 'release:close'
// util
| 'util:clear-cache'
// testing
| '_test:google-calendar'
| '_test:slack'
Expand Down Expand Up @@ -258,7 +260,7 @@ If you have changes that should go into this patch release, <${patchRequestTempl
owner: 'sourcegraph',
repo: 'sourcegraph',
base: 'main',
head: `publish-${release.version}`,
head: `changelog-${release.version}`,
title: prMessage,
commitMessage: prMessage,
edits: [
Expand All @@ -281,7 +283,7 @@ If you have changes that should go into this patch release, <${patchRequestTempl
// Update changelog
writeFileSync(changelogPath, changelogContents)
},
], // Changes already done
],
},
],
dryRun: config.dryRun.changesets,
Expand Down Expand Up @@ -612,6 +614,13 @@ Campaign: ${campaignURL}`,
}
},
},
{
id: 'util:clear-cache',
description: 'Clear release tool cache',
run: () => {
rmdirSync(cacheFolder, { recursive: true })
},
},
{
id: '_test:google-calendar',
description: 'Test Google Calendar integration',
Expand Down
4 changes: 2 additions & 2 deletions dev/release/src/slack.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import got from 'got'
import { readLine } from './util'
import { readLine, cacheFolder } from './util'

export async function postMessage(message: string, channel: string): Promise<void> {
const webhookURL = await readLine(
`Enter the Slack webhook URL corresponding to the #${channel} channel (https://api.slack.com/apps/APULW2LKS/incoming-webhooks?): `,
`.secrets/slackWebhookURL-${channel}.txt`
`${cacheFolder}/slackWebhookURL-${channel}.txt`
)
await got.post(webhookURL, {
body: JSON.stringify({ text: message, link_names: true }),
Expand Down
2 changes: 2 additions & 0 deletions dev/release/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export function timezoneLink(date: Date, linkName: string): string {
})}_${date.getUTCFullYear()}_in_UTC?${encodeURI(linkName)}`
}

export const cacheFolder = './.secrets'

export async function readLine(prompt: string, cacheFile?: string): Promise<string> {
if (!cacheFile) {
return readLineNoCache(prompt)
Expand Down