Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

offline mode #153

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
7 changes: 7 additions & 0 deletions src/command-line-arguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type CommandLineArguments = {
reset: boolean;
backport: boolean;
defaultBranch: string;
fetchRemote: boolean;
};

/**
Expand Down Expand Up @@ -51,6 +52,12 @@ export async function readCommandLineArguments(
default: 'main',
type: 'string',
})
.option('fetch-remote', {
alias: 'f',
describe: 'Syncronizes local git references with remote',
default: true,
type: 'boolean',
})
.help()
.strict()
.parse();
Expand Down
24 changes: 17 additions & 7 deletions src/initial-parameters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ describe('initial-parameters', () => {
reset: true,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand All @@ -56,6 +57,7 @@ describe('initial-parameters', () => {
reset: true,
releaseType: 'ordinary',
defaultBranch: 'main',
fetchRemote: true,
});
});

Expand All @@ -72,6 +74,7 @@ describe('initial-parameters', () => {
reset: true,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
Expand All @@ -88,6 +91,7 @@ describe('initial-parameters', () => {

expect(readProjectSpy).toHaveBeenCalledWith('/path/to/cwd/project', {
stderr,
fetchRemote: true,
});
});

Expand All @@ -102,12 +106,13 @@ describe('initial-parameters', () => {
reset: true,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand All @@ -132,12 +137,13 @@ describe('initial-parameters', () => {
reset: true,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand All @@ -162,12 +168,13 @@ describe('initial-parameters', () => {
reset: true,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand All @@ -190,12 +197,13 @@ describe('initial-parameters', () => {
reset: false,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand All @@ -218,12 +226,13 @@ describe('initial-parameters', () => {
reset: false,
backport: true,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand All @@ -246,12 +255,13 @@ describe('initial-parameters', () => {
reset: false,
backport: false,
defaultBranch: 'main',
fetchRemote: true,
});
jest
.spyOn(envModule, 'getEnvironmentVariables')
.mockReturnValue({ EDITOR: undefined });
when(jest.spyOn(projectModule, 'readProject'))
.calledWith('/path/to/project', { stderr })
.calledWith('/path/to/project', { stderr, fetchRemote: true })
.mockResolvedValue(project);

const initialParameters = await determineInitialParameters({
Expand Down
7 changes: 6 additions & 1 deletion src/initial-parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type InitialParameters = {
reset: boolean;
releaseType: ReleaseType;
defaultBranch: string;
fetchRemote: boolean;
};

/**
Expand All @@ -45,7 +46,10 @@ export async function determineInitialParameters({
const args = await readCommandLineArguments(argv);

const projectDirectoryPath = path.resolve(cwd, args.projectDirectory);
const project = await readProject(projectDirectoryPath, { stderr });
const project = await readProject(projectDirectoryPath, {
stderr,
fetchRemote: args.fetchRemote,
});
const tempDirectoryPath =
args.tempDirectory === undefined
? path.join(
Expand All @@ -61,5 +65,6 @@ export async function determineInitialParameters({
reset: args.reset,
defaultBranch: args.defaultBranch,
releaseType: args.backport ? 'backport' : 'ordinary',
fetchRemote: args.fetchRemote,
};
}
3 changes: 3 additions & 0 deletions src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('main', () => {
reset: true,
defaultBranch: 'main',
releaseType: 'backport',
fetchRemote: true,
});
const followMonorepoWorkflowSpy = jest
.spyOn(monorepoWorkflowOperations, 'followMonorepoWorkflow')
Expand All @@ -40,6 +41,7 @@ describe('main', () => {
defaultBranch: 'main',
stdout,
stderr,
fetchRemote: true,
});
});

Expand All @@ -55,6 +57,7 @@ describe('main', () => {
reset: false,
defaultBranch: 'main',
releaseType: 'backport',
fetchRemote: true,
});
const followMonorepoWorkflowSpy = jest
.spyOn(monorepoWorkflowOperations, 'followMonorepoWorkflow')
Expand Down
11 changes: 9 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ export async function main({
stdout: Pick<WriteStream, 'write'>;
stderr: Pick<WriteStream, 'write'>;
}) {
const { project, tempDirectoryPath, reset, releaseType, defaultBranch } =
await determineInitialParameters({ argv, cwd, stderr });
const {
project,
tempDirectoryPath,
reset,
releaseType,
defaultBranch,
fetchRemote,
} = await determineInitialParameters({ argv, cwd, stderr });

if (project.isMonorepo) {
stdout.write(
Expand All @@ -40,6 +46,7 @@ export async function main({
defaultBranch,
stdout,
stderr,
fetchRemote,
});
} else {
stdout.write(
Expand Down
5 changes: 4 additions & 1 deletion src/monorepo-workflow-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
* @param args.defaultBranch - The name of the default branch in the repository.
* @param args.stdout - A stream that can be used to write to standard out.
* @param args.stderr - A stream that can be used to write to standard error.
* @param args.fetchRemote - Whether to synchronize local tags with remote.
*/
export async function followMonorepoWorkflow({
project,
Expand All @@ -68,6 +69,7 @@ export async function followMonorepoWorkflow({
defaultBranch,
stdout,
stderr,
fetchRemote,
}: {
project: Project;
tempDirectoryPath: string;
Expand All @@ -76,14 +78,15 @@ export async function followMonorepoWorkflow({
defaultBranch: string;
stdout: Pick<WriteStream, 'write'>;
stderr: Pick<WriteStream, 'write'>;
fetchRemote?: boolean;
}) {
const { version: newReleaseVersion, firstRun } = await createReleaseBranch({
project,
releaseType,
});

if (firstRun) {
await updateChangelogsForChangedPackages({ project, stderr });
await updateChangelogsForChangedPackages({ project, stderr, fetchRemote });
await commitAllChanges(
project.directoryPath,
`Initialize Release ${newReleaseVersion}`,
Expand Down
4 changes: 4 additions & 0 deletions src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,16 +301,19 @@
* @param args.project - The project.
* @param args.package - A particular package in the project.
* @param args.stderr - A stream that can be used to write to standard error.
* @param args.fetchRemote - Whether to synchronize local tags with remote.
* @returns The result of writing to the changelog.
*/
export async function updatePackageChangelog({
project: { repositoryUrl },
package: pkg,
stderr,
fetchRemote,
}: {
project: Pick<Project, 'directoryPath' | 'repositoryUrl'>;
package: Package;
stderr: Pick<WriteStream, 'write'>;
fetchRemote?: boolean | undefined;
}): Promise<void> {
let changelogContent;

Expand All @@ -337,6 +340,7 @@
repoUrl: repositoryUrl,
tagPrefixes: [`${pkg.validatedManifest.name}@`, 'v'],
formatter: formatChangelog,
fetchRemote,

Check failure on line 343 in src/package.ts

View workflow job for this annotation

GitHub Actions / Build (16.x)

Argument of type '{ changelogContent: string; isReleaseCandidate: false; projectRootDirectory: string; repoUrl: string; tagPrefixes: [string, string]; formatter: (changelog: string) => string; fetchRemote: boolean | undefined; }' is not assignable to parameter of type 'UpdateChangelogOptions'.

Check failure on line 343 in src/package.ts

View workflow job for this annotation

GitHub Actions / Build (18.x)

Argument of type '{ changelogContent: string; isReleaseCandidate: false; projectRootDirectory: string; repoUrl: string; tagPrefixes: [string, string]; formatter: (changelog: string) => string; fetchRemote: boolean | undefined; }' is not assignable to parameter of type 'UpdateChangelogOptions'.

Check failure on line 343 in src/package.ts

View workflow job for this annotation

GitHub Actions / Build (20.x)

Argument of type '{ changelogContent: string; isReleaseCandidate: false; projectRootDirectory: string; repoUrl: string; tagPrefixes: [string, string]; formatter: (changelog: string) => string; fetchRemote: boolean | undefined; }' is not assignable to parameter of type 'UpdateChangelogOptions'.
});

if (newChangelogContent) {
Expand Down
7 changes: 5 additions & 2 deletions src/project.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('project', () => {
.calledWith(projectDirectoryPath)
.mockResolvedValue(projectRepositoryUrl);
when(jest.spyOn(repoModule, 'getTagNames'))
.calledWith(projectDirectoryPath)
.calledWith(projectDirectoryPath, true)
.mockResolvedValue(projectTagNames);
when(jest.spyOn(packageModule, 'readMonorepoRootPackage'))
.calledWith({
Expand Down Expand Up @@ -111,7 +111,10 @@ describe('project', () => {
);

expect(
await readProject(projectDirectoryPath, { stderr }),
await readProject(projectDirectoryPath, {
stderr,
fetchRemote: true,
}),
).toStrictEqual({
directoryPath: projectDirectoryPath,
repositoryUrl: projectRepositoryUrl,
Expand Down
9 changes: 7 additions & 2 deletions src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,18 @@ function examineReleaseVersion(packageVersion: SemVer): ReleaseVersion {
* @param projectDirectoryPath - The path to the project.
* @param args - Additional arguments.
* @param args.stderr - A stream that can be used to write to standard error.
* @param args.fetchRemote - Whether to synchronize local tags with remote.
* @returns An object that represents information about the project.
* @throws if the project does not contain a root `package.json` (polyrepo and
* monorepo) or if any of the workspaces specified in the root `package.json` do
* not have `package.json`s (monorepo only).
*/
export async function readProject(
projectDirectoryPath: string,
{ stderr }: { stderr: WriteStreamLike },
{ fetchRemote, stderr }: { fetchRemote?: boolean; stderr: WriteStreamLike },
): Promise<Project> {
const repositoryUrl = await getRepositoryHttpsUrl(projectDirectoryPath);
const tagNames = await getTagNames(projectDirectoryPath);
const tagNames = await getTagNames(projectDirectoryPath, fetchRemote);
const rootPackage = await readMonorepoRootPackage({
packageDirectoryPath: projectDirectoryPath,
projectDirectoryPath,
Expand Down Expand Up @@ -135,17 +136,20 @@ export async function readProject(
* @param args - The arguments.
* @param args.project - The project.
* @param args.stderr - A stream that can be used to write to standard error.
* @param args.fetchRemote - Whether to synchronize local tags with remote.
* @returns The result of writing to the changelog.
*/
export async function updateChangelogsForChangedPackages({
project,
stderr,
fetchRemote,
}: {
project: Pick<
Project,
'directoryPath' | 'repositoryUrl' | 'workspacePackages'
>;
stderr: Pick<WriteStream, 'write'>;
fetchRemote?: boolean | undefined;
}): Promise<void> {
await Promise.all(
Object.values(project.workspacePackages)
Expand All @@ -157,6 +161,7 @@ export async function updateChangelogsForChangedPackages({
project,
package: pkg,
stderr,
fetchRemote,
}),
),
);
Expand Down
2 changes: 1 addition & 1 deletion src/repo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe('repo', () => {
})
.mockResolvedValue(['tag1', 'tag2', 'tag3']);

expect(await getTagNames('/path/to/repo')).toStrictEqual([
expect(await getTagNames('/path/to/repo', false)).toStrictEqual([
'tag1',
'tag2',
'tag3',
Expand Down
6 changes: 5 additions & 1 deletion src/repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,17 @@ export async function branchExists(
* advised to only run this once.
*
* @param repositoryDirectoryPath - The path to the repository directory.
* @param fetchRemote - Whether to synchronize local tags with remote.
* @returns The names of the tags.
* @throws If no tags are found and the local git history is incomplete.
*/
export async function getTagNames(
repositoryDirectoryPath: string,
fetchRemote?: boolean,
): Promise<string[]> {
await runGitCommandWithin(repositoryDirectoryPath, 'fetch', ['--tags']);
if (typeof fetchRemote !== 'boolean' || fetchRemote) {
await runGitCommandWithin(repositoryDirectoryPath, 'fetch', ['--tags']);
}

const tagNames = await getLinesFromGitCommandWithin(
repositoryDirectoryPath,
Expand Down
Loading