-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
490d9ed
commit 82fc010
Showing
3 changed files
with
227 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ import { GithubClient } from './github_client.js'; | |
import assert from 'node:assert'; | ||
import { ReleaseDeprecator } from './release_deprecator.js'; | ||
import { DistTagMover } from './dist_tag_mover.js'; | ||
import { ReleaseRestorer } from './release_restorer.js'; | ||
|
||
/** | ||
* This test suite is more of an integration test than a unit test. | ||
|
@@ -43,19 +44,19 @@ void describe('ReleaseLifecycleManager', async () => { | |
* It seeds the local npm proxy with a few releases of these packages. | ||
* When its done, the state of the git refs npm dist-tags should be as follows: | ||
* | ||
* third release commit ● <- HEAD, cantaloupe@1.3.0, cantaloupe@latest | ||
* third release commit ● <- HEAD, cantaloupe@1.2.0, cantaloupe@latest | ||
* | | ||
* minor bump of cantaloupe only ● | ||
* | | ||
* second release commit ● <- [email protected], [email protected], platypus@latest | ||
* second release commit ● <- [email protected], platypus@latest | ||
* | | ||
* minor bump of cantaloupe and platypus ● | ||
* | | ||
* first release commit ● <- [email protected], [email protected] | ||
* | | ||
* minor bump of cantaloupe and platypus ● | ||
* | | ||
* initial commit ● <- [email protected], [email protected] | ||
* baseline release ● <- [email protected], [email protected] | ||
* | ||
*/ | ||
beforeEach(async ({ name: testName }) => { | ||
|
@@ -99,7 +100,7 @@ void describe('ReleaseLifecycleManager', async () => { | |
await npmClient.install(['@changesets/cli']); | ||
|
||
await $`npx changeset init`; | ||
await gitClient.commitAllChanges('initial commit'); | ||
await gitClient.commitAllChanges('Version Packages (baseline release)'); | ||
await runPublishInTestDir(); | ||
|
||
await commitVersionBumpChangeset( | ||
|
@@ -115,7 +116,7 @@ void describe('ReleaseLifecycleManager', async () => { | |
await commitVersionBumpChangeset( | ||
testWorkingDir, | ||
gitClient, | ||
[cantaloupePackageName, platypusPackageName], | ||
[platypusPackageName], | ||
'minor' | ||
); | ||
await runVersionInTestDir(); | ||
|
@@ -131,33 +132,225 @@ void describe('ReleaseLifecycleManager', async () => { | |
await runVersionInTestDir(); | ||
await gitClient.commitAllChanges('Version Packages (third release)'); | ||
await runPublishInTestDir(); | ||
|
||
// sanity check initial state | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.2.0', | ||
'latest' | ||
); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
platypusPackageName, | ||
'1.2.0', | ||
'latest' | ||
); | ||
}); | ||
|
||
void it('dummy test', async () => { | ||
void it('can deprecate and restore packages using npm metadata', async () => { | ||
const githubClient = new GithubClient('garbage'); | ||
mock.method(githubClient, 'createPr', async () => ({ prUrl: 'testPrUrl' })); | ||
mock.method(gitClient, 'push', async () => {}); | ||
const releaseDeprecator = new ReleaseDeprecator( | ||
const distTagMover = new DistTagMover(npmClient); | ||
const releaseDeprecator1 = new ReleaseDeprecator( | ||
'HEAD', | ||
'the cantaloupe is rotten', | ||
githubClient, | ||
gitClient, | ||
npmClient, | ||
new DistTagMover(npmClient) | ||
distTagMover | ||
); | ||
await releaseDeprecator1.deprecateRelease(); | ||
|
||
// expect [email protected] to be deprecated and cantaloupe@latest = 1.1.0 | ||
await expectDeprecated( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.2.0', | ||
'the cantaloupe is rotten' | ||
); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.1.0', | ||
'latest' | ||
); | ||
|
||
// now deprecate the platypus release | ||
|
||
await gitClient.switchToBranch('main'); | ||
const releaseDeprecator2 = new ReleaseDeprecator( | ||
'HEAD~', | ||
'RIP platypus', | ||
githubClient, | ||
gitClient, | ||
npmClient, | ||
distTagMover | ||
); | ||
|
||
await releaseDeprecator2.deprecateRelease(); | ||
|
||
// expect [email protected] to be deprecated and platypus@latest = 1.1.0 | ||
await expectDeprecated( | ||
npmClient, | ||
platypusPackageName, | ||
'1.2.0', | ||
'RIP platypus' | ||
); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
platypusPackageName, | ||
'1.1.0', | ||
'latest' | ||
); | ||
|
||
// now deprecate the 1.1.0 release of both packages | ||
|
||
await gitClient.switchToBranch('main'); | ||
const releaseDeprecator3 = new ReleaseDeprecator( | ||
'HEAD~3', | ||
'real big mess', | ||
githubClient, | ||
gitClient, | ||
npmClient, | ||
distTagMover | ||
); | ||
|
||
await releaseDeprecator3.deprecateRelease(); | ||
|
||
// expect [email protected] and [email protected] to be deprecated and @latest points to 1.0.0 for both | ||
await expectDeprecated( | ||
npmClient, | ||
platypusPackageName, | ||
'1.1.0', | ||
'real big mess' | ||
); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
platypusPackageName, | ||
'1.0.0', | ||
'latest' | ||
); | ||
await expectDeprecated( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.1.0', | ||
'real big mess' | ||
); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.0.0', | ||
'latest' | ||
); | ||
|
||
/* To validate the restore scenarios, we now "undo" the rollbacks */ | ||
|
||
await gitClient.switchToBranch('main'); | ||
const releaseRestorer1 = new ReleaseRestorer( | ||
'HEAD~3', | ||
githubClient, | ||
gitClient, | ||
npmClient, | ||
distTagMover | ||
); | ||
|
||
await releaseRestorer1.restoreRelease(); | ||
|
||
// expect [email protected] and [email protected] to be @latest and no longer deprecated | ||
await expectNotDeprecated(npmClient, platypusPackageName, '1.1.0'); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
platypusPackageName, | ||
'1.1.0', | ||
'latest' | ||
); | ||
await expectNotDeprecated(npmClient, cantaloupePackageName, '1.1.0'); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.1.0', | ||
'latest' | ||
); | ||
|
||
await gitClient.switchToBranch('main'); | ||
const releaseRestorer2 = new ReleaseRestorer( | ||
'HEAD~', | ||
githubClient, | ||
gitClient, | ||
npmClient, | ||
distTagMover | ||
); | ||
|
||
await releaseRestorer2.restoreRelease(); | ||
|
||
// expect [email protected] to @latest and no longer deprecated | ||
await expectNotDeprecated(npmClient, platypusPackageName, '1.2.0'); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
platypusPackageName, | ||
'1.2.0', | ||
'latest' | ||
); | ||
await releaseDeprecator.deprecateRelease(); | ||
// switch back to the original branch | ||
|
||
await gitClient.switchToBranch('main'); | ||
const releaseRestorer3 = new ReleaseRestorer( | ||
'HEAD', | ||
githubClient, | ||
gitClient, | ||
npmClient, | ||
distTagMover | ||
); | ||
|
||
// expect latest of cantaloupe to point back to 1.2.0 and 1.3.0 to be marked deprecated | ||
await releaseRestorer3.restoreRelease(); | ||
|
||
const { 'dist-tags': distTags, deprecated } = | ||
await npmClient.getPackageInfo(`${cantaloupePackageName}@1.3.0`); | ||
assert.equal(distTags.latest, '1.2.0'); | ||
assert.equal(deprecated, 'the cantaloupe is rotten'); | ||
// expect [email protected] to be @latest and no longer deprecated | ||
await expectNotDeprecated(npmClient, cantaloupePackageName, '1.2.0'); | ||
await expectDistTagAtVersion( | ||
npmClient, | ||
cantaloupePackageName, | ||
'1.2.0', | ||
'latest' | ||
); | ||
|
||
// We are now back to the original state having deprecated and then restored 3 releases | ||
}); | ||
}); | ||
|
||
const expectDeprecated = async ( | ||
npmClient: NpmClient, | ||
packageName: string, | ||
version: string, | ||
deprecationMessage: string | ||
) => { | ||
const { deprecated } = await npmClient.getPackageInfo( | ||
`${packageName}@${version}` | ||
); | ||
assert.equal(deprecated, deprecationMessage); | ||
}; | ||
|
||
const expectNotDeprecated = async ( | ||
npmClient: NpmClient, | ||
packageName: string, | ||
version: string | ||
) => { | ||
const { deprecated } = await npmClient.getPackageInfo( | ||
`${packageName}@${version}` | ||
); | ||
assert.equal(deprecated, undefined); | ||
}; | ||
|
||
const expectDistTagAtVersion = async ( | ||
npmClient: NpmClient, | ||
packageName: string, | ||
version: string, | ||
distTag: string | ||
) => { | ||
const { 'dist-tags': distTags } = await npmClient.getPackageInfo(packageName); | ||
assert.equal(distTags[distTag], version); | ||
}; | ||
|
||
const setPackageToPublic = async (packagePath: string) => { | ||
const packageJson = await readPackageJson(packagePath); | ||
packageJson.publishConfig = { | ||
|