Skip to content
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
17 changes: 10 additions & 7 deletions scripts/release-status.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -136,26 +136,29 @@ export async function readReleaseRevision(repositoryRoot, version) {
const manifestPath = 'packages/charts-core/package.json'
const { stdout } = await execFileAsync(
'git',
['log', '--full-history', '--format=%H%x09%s', 'HEAD', '--', manifestPath],
['log', '--first-parent', '--format=%H', 'HEAD', '--', manifestPath],
{
cwd: repositoryRoot,
env: { ...process.env },
maxBuffer: 5 * 1024 * 1024,
},
)
const revisions = stdout.trim().split('\n').filter(Boolean)
for (const entry of revisions) {
const [revision, ...subjectParts] = entry.split('\t')
const subject = subjectParts.join('\t')
if (!revision || !/changeset-release\/main/i.test(subject)) continue
for (const revision of revisions) {
const currentVersion = await readManifestVersionAt(
repositoryRoot,
revision,
manifestPath,
)
if (currentVersion === version) return revision
if (currentVersion !== version) continue
const previousVersion = await readManifestVersionAt(
repositoryRoot,
`${revision}^1`,
manifestPath,
)
if (previousVersion !== version) return revision
}
assert.fail(`Could not find the release merge revision for ${version}`)
assert.fail(`Could not find the release revision for ${version}`)
}

async function readManifestVersionAt(repositoryRoot, revision, manifestPath) {
Expand Down
134 changes: 88 additions & 46 deletions scripts/release-status.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -158,55 +158,97 @@ describe('automated release status', () => {
).toThrow('existing release tag points to a different revision')
})

it('finds the changesets merge that introduced the current version', async () => {
const repositoryRoot = await mkdtemp(
join(tmpdir(), 'charts-release-status-'),
)

try {
await git(repositoryRoot, 'init', '--initial-branch=main')
await git(repositoryRoot, 'config', 'user.name', 'Release Status Test')
await git(
repositoryRoot,
'config',
'user.email',
'release-status@example.com',
)
await git(repositoryRoot, 'config', 'commit.gpgsign', 'false')
await git(repositoryRoot, 'config', 'merge.gpgsign', 'false')
await git(repositoryRoot, 'config', 'core.hooksPath', '.git/no-hooks')

const manifestDirectory = join(repositoryRoot, 'packages', 'charts-core')
const manifestPath = join(manifestDirectory, 'package.json')
await mkdir(manifestDirectory, { recursive: true })
await writeManifest(manifestPath, '0.6.4')
await git(repositoryRoot, 'add', 'packages/charts-core/package.json')
await git(repositoryRoot, 'commit', '-m', 'chore: initial version')

await git(repositoryRoot, 'switch', '-c', 'changeset-release/main')
await writeManifest(manifestPath, '0.6.5')
await git(repositoryRoot, 'add', 'packages/charts-core/package.json')
await git(repositoryRoot, 'commit', '-m', 'chore: version packages')

await git(repositoryRoot, 'switch', 'main')
await git(
repositoryRoot,
'merge',
'--no-ff',
'changeset-release/main',
'-m',
'Merge pull request #1 from TanStack/changeset-release/main',
it.each(['merge', 'squash', 'rebase'])(
'finds the version introduction after a %s merge',
async (method) => {
const repositoryRoot = await mkdtemp(
join(tmpdir(), 'charts-release-status-'),
)

const { stdout } = await git(repositoryRoot, 'rev-parse', 'HEAD')
const expectedRevision = stdout.trim()
const revision = await readReleaseRevision(repositoryRoot, '0.6.5')
try {
await git(repositoryRoot, 'init', '--initial-branch=main')
await git(repositoryRoot, 'config', 'user.name', 'Release Status Test')
await git(
repositoryRoot,
'config',
'user.email',
'release-status@example.com',
)
await git(repositoryRoot, 'config', 'commit.gpgsign', 'false')
await git(repositoryRoot, 'config', 'merge.gpgsign', 'false')
await git(repositoryRoot, 'config', 'core.hooksPath', '.git/no-hooks')

expect(revision).toBe(expectedRevision)
} finally {
await rm(repositoryRoot, { recursive: true, force: true })
}
})
const manifestDirectory = join(
repositoryRoot,
'packages',
'charts-core',
)
const manifestPath = join(manifestDirectory, 'package.json')
await mkdir(manifestDirectory, { recursive: true })
await writeManifest(manifestPath, '0.6.4')
await git(repositoryRoot, 'add', 'packages/charts-core/package.json')
await git(repositoryRoot, 'commit', '-m', 'chore: initial version')

await git(repositoryRoot, 'switch', '-c', 'changeset-release/main')
await writeManifest(manifestPath, '0.6.5')
await git(repositoryRoot, 'add', 'packages/charts-core/package.json')
await git(repositoryRoot, 'commit', '-m', 'chore: version packages')

await git(repositoryRoot, 'switch', 'main')
if (method === 'merge') {
await git(
repositoryRoot,
'merge',
'--no-ff',
'changeset-release/main',
'-m',
'Merge pull request #1 from TanStack/changeset-release/main',
)
} else if (method === 'squash') {
await git(
repositoryRoot,
'merge',
'--squash',
'changeset-release/main',
)
await git(repositoryRoot, 'commit', '-m', 'ci: Version Packages (#1)')
} else {
await git(
repositoryRoot,
'merge',
'--ff-only',
'changeset-release/main',
)
}

const { stdout } = await git(repositoryRoot, 'rev-parse', 'HEAD')
const expectedRevision = stdout.trim()
await writeFile(
manifestPath,
JSON.stringify({
name: '@tanstack/charts',
version: '0.6.5',
description: 'Later manifest change',
}),
)
await git(repositoryRoot, 'add', 'packages/charts-core/package.json')
await git(
repositoryRoot,
'commit',
'-m',
'chore: update package description',
)
const revision = await readReleaseRevision(repositoryRoot, '0.6.5')

expect(revision).toBe(expectedRevision)
await expect(
readReleaseRevision(repositoryRoot, '9.9.9'),
).rejects.toThrow('Could not find the release revision for 9.9.9')
} finally {
await rm(repositoryRoot, { recursive: true, force: true })
}
},
)
})

function git(repositoryRoot, ...args) {
Expand Down