Skip to content

Commit 660b7e5

Browse files
committed
feat: ci cmd
1 parent 3fa1c35 commit 660b7e5

File tree

15 files changed

+233
-119
lines changed

15 files changed

+233
-119
lines changed

.changeset/odd-pets-divide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"lingo.dev": minor
3+
---
4+
5+
add `ci` cmd

action.yml

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,16 @@ branding:
99
runs:
1010
using: "composite"
1111
steps:
12-
- name: Install pnpm
13-
run: cd ${{ github.action_path }} && npm install -g pnpm && pnpm install
14-
shell: bash
15-
- name: Build
16-
run: cd ${{ github.action_path }}/action && pnpm build
17-
shell: bash
1812
- name: Run
19-
run: node ${{ github.action_path }}/action/build/index.js
13+
run: |
14+
npx lingo.dev@latest ci \
15+
--api-key ${{ inputs.api-key }} \
16+
--pull-request ${{ inputs.pull-request }} \
17+
--commit-message ${{ inputs.commit-message }} \
18+
--pull-request-title ${{ inputs.pull-request-title }} \
19+
--working-directory ${{ inputs.working-directory }} \
20+
--process-own-commits ${{ inputs.process-own-commits }}
2021
shell: bash
21-
env:
22-
LINGODOTDEV_API_KEY: ${{ inputs.api-key }}
23-
LINGODOTDEV_PULL_REQUEST: ${{ inputs.pull-request }}
24-
LINGODOTDEV_COMMIT_MESSAGE: ${{ inputs.commit-message }}
25-
LINGODOTDEV_PULL_REQUEST_TITLE: ${{ inputs.pull-request-title }}
26-
LINGODOTDEV_WORKING_DIRECTORY: ${{ inputs.working-directory }}
27-
LINGODOTDEV_PROCESS_OWN_COMMITS: ${{ inputs.process-own-commits }}
2822
inputs:
2923
api-key:
3024
description: "Lingo.dev Platform API Key"

action/src/index.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

action/src/main.d.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

action/src/main.ts

Lines changed: 0 additions & 30 deletions
This file was deleted.

packages/cli/src/action

Lines changed: 0 additions & 1 deletion
This file was deleted.

action/src/flows/_base.ts renamed to packages/cli/src/cli/cmd/ci/flows/_base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Ora } from "ora";
2-
import { PlatformKit } from "../platforms/_base.js";
2+
import { PlatformKit } from "../platforms/_base";
33

44
export interface IIntegrationFlow {
55
preRun?(): Promise<boolean>;

action/src/flows/in-branch.ts renamed to packages/cli/src/cli/cmd/ci/flows/in-branch.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { execSync } from "child_process";
22
import path from "path";
3-
import { gitConfig, IntegrationFlow } from "./_base.js";
3+
import { gitConfig, IntegrationFlow } from "./_base";
44

55
export class InBranchFlow extends IntegrationFlow {
66
async preRun() {
@@ -32,10 +32,14 @@ export class InBranchFlow extends IntegrationFlow {
3232
this.ora.succeed("Changes committed");
3333

3434
this.ora.start("Pushing changes to remote");
35-
const currentBranch = this.i18nBranchName ?? this.platformKit.platformConfig.baseBranchName;
36-
execSync(`git push origin ${currentBranch} ${forcePush ? "--force" : ""}`, {
37-
stdio: "inherit",
38-
});
35+
const currentBranch =
36+
this.i18nBranchName ?? this.platformKit.platformConfig.baseBranchName;
37+
execSync(
38+
`git push origin ${currentBranch} ${forcePush ? "--force" : ""}`,
39+
{
40+
stdio: "inherit",
41+
},
42+
);
3943
this.ora.succeed("Changes pushed to remote");
4044
}
4145

@@ -51,7 +55,10 @@ export class InBranchFlow extends IntegrationFlow {
5155
}
5256

5357
private async runLingoDotDev() {
54-
execSync(`npx lingo.dev@latest i18n --api-key ${this.platformKit.config.replexicaApiKey}`, { stdio: "inherit" });
58+
execSync(
59+
`npx lingo.dev@latest i18n --api-key ${this.platformKit.config.replexicaApiKey}`,
60+
{ stdio: "inherit" },
61+
);
5562
}
5663

5764
private configureGit() {
@@ -75,7 +82,9 @@ export class InBranchFlow extends IntegrationFlow {
7582

7683
if (!processOwnCommits) {
7784
const currentAuthor = `${gitConfig.userName} <${gitConfig.userEmail}>`;
78-
const authorOfLastCommit = execSync(`git log -1 --pretty=format:'%an <%ae>'`).toString();
85+
const authorOfLastCommit = execSync(
86+
`git log -1 --pretty=format:'%an <%ae>'`,
87+
).toString();
7988
if (authorOfLastCommit === currentAuthor) {
8089
this.ora.warn(
8190
`The last commit was already made by ${currentAuthor}, so this run will be skipped, as running again would have no effect. See docs: https://docs.lingo.dev/ci-action/overview`,
@@ -84,9 +93,14 @@ export class InBranchFlow extends IntegrationFlow {
8493
}
8594
}
8695

87-
const workingDir = path.resolve(process.cwd(), this.platformKit.config.workingDir);
96+
const workingDir = path.resolve(
97+
process.cwd(),
98+
this.platformKit.config.workingDir,
99+
);
88100
if (workingDir !== process.cwd()) {
89-
this.ora.info(`Changing to working directory: ${this.platformKit.config.workingDir}`);
101+
this.ora.info(
102+
`Changing to working directory: ${this.platformKit.config.workingDir}`,
103+
);
90104
process.chdir(workingDir);
91105
}
92106

action/src/flows/pull-request.ts renamed to packages/cli/src/cli/cmd/ci/flows/pull-request.ts

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { execSync } from "child_process";
2-
import { InBranchFlow } from "./in-branch.js";
2+
import { InBranchFlow } from "./in-branch";
33

44
export class PullRequestFlow extends InBranchFlow {
55
async preRun() {
@@ -10,7 +10,9 @@ export class PullRequestFlow extends InBranchFlow {
1010

1111
this.ora.start("Calculating automated branch name");
1212
this.i18nBranchName = this.calculatePrBranchName();
13-
this.ora.succeed(`Automated branch name calculated: ${this.i18nBranchName}`);
13+
this.ora.succeed(
14+
`Automated branch name calculated: ${this.i18nBranchName}`,
15+
);
1416

1517
this.ora.start("Checking if branch exists");
1618
const branchExists = await this.checkBranchExistance(this.i18nBranchName);
@@ -21,7 +23,9 @@ export class PullRequestFlow extends InBranchFlow {
2123
this.checkoutI18nBranch(this.i18nBranchName);
2224
this.ora.succeed(`Checked out branch ${this.i18nBranchName}`);
2325

24-
this.ora.start(`Syncing with ${this.platformKit.platformConfig.baseBranchName}`);
26+
this.ora.start(
27+
`Syncing with ${this.platformKit.platformConfig.baseBranchName}`,
28+
);
2529
this.syncI18nBranch();
2630
this.ora.succeed(`Checked out and synced branch ${this.i18nBranchName}`);
2731
} else {
@@ -39,13 +43,17 @@ export class PullRequestFlow extends InBranchFlow {
3943

4044
async postRun() {
4145
if (!this.i18nBranchName) {
42-
throw new Error("i18nBranchName is not set. Did you forget to call preRun?");
46+
throw new Error(
47+
"i18nBranchName is not set. Did you forget to call preRun?",
48+
);
4349
}
4450

4551
this.ora.start("Checking if PR already exists");
4652
const pullRequestNumber = await this.ensureFreshPr(this.i18nBranchName);
4753
// await this.createLabelIfNotExists(pullRequestNumber, 'lingo.dev/i18n', false);
48-
this.ora.succeed(`Pull request ready: ${this.platformKit.buildPullRequestUrl(pullRequestNumber)}`);
54+
this.ora.succeed(
55+
`Pull request ready: ${this.platformKit.buildPullRequestUrl(pullRequestNumber)}`,
56+
);
4957
}
5058

5159
private calculatePrBranchName(): string {
@@ -61,7 +69,7 @@ export class PullRequestFlow extends InBranchFlow {
6169
private async ensureFreshPr(i18nBranchName: string) {
6270
// Check if PR exists
6371
this.ora.start(
64-
`Checking for existing PR with head ${i18nBranchName} and base ${this.platformKit.platformConfig.baseBranchName}`
72+
`Checking for existing PR with head ${i18nBranchName} and base ${this.platformKit.platformConfig.baseBranchName}`,
6573
);
6674
let prNumber = await this.platformKit.getOpenPullRequestNumber({
6775
branch: i18nBranchName,
@@ -92,12 +100,19 @@ export class PullRequestFlow extends InBranchFlow {
92100

93101
private createI18nBranch(i18nBranchName: string) {
94102
try {
95-
execSync(`git fetch origin ${this.platformKit.platformConfig.baseBranchName}`, { stdio: "inherit" });
96-
execSync(`git checkout -b ${i18nBranchName} origin/${this.platformKit.platformConfig.baseBranchName}`, {
97-
stdio: "inherit",
98-
});
103+
execSync(
104+
`git fetch origin ${this.platformKit.platformConfig.baseBranchName}`,
105+
{ stdio: "inherit" },
106+
);
107+
execSync(
108+
`git checkout -b ${i18nBranchName} origin/${this.platformKit.platformConfig.baseBranchName}`,
109+
{
110+
stdio: "inherit",
111+
},
112+
);
99113
} catch (error) {
100-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
114+
const errorMessage =
115+
error instanceof Error ? error.message : "Unknown error occurred";
101116
this.ora.fail(`Failed to create branch: ${errorMessage}`);
102117
this.ora.info(`
103118
Troubleshooting tips:
@@ -114,13 +129,23 @@ export class PullRequestFlow extends InBranchFlow {
114129
throw new Error("i18nBranchName is not set");
115130
}
116131

117-
this.ora.start(`Fetching latest changes from ${this.platformKit.platformConfig.baseBranchName}`);
118-
execSync(`git fetch origin ${this.platformKit.platformConfig.baseBranchName}`, { stdio: "inherit" });
119-
this.ora.succeed(`Fetched latest changes from ${this.platformKit.platformConfig.baseBranchName}`);
132+
this.ora.start(
133+
`Fetching latest changes from ${this.platformKit.platformConfig.baseBranchName}`,
134+
);
135+
execSync(
136+
`git fetch origin ${this.platformKit.platformConfig.baseBranchName}`,
137+
{ stdio: "inherit" },
138+
);
139+
this.ora.succeed(
140+
`Fetched latest changes from ${this.platformKit.platformConfig.baseBranchName}`,
141+
);
120142

121143
try {
122144
this.ora.start("Attempting to rebase branch");
123-
execSync(`git rebase origin/${this.platformKit.platformConfig.baseBranchName}`, { stdio: "inherit" });
145+
execSync(
146+
`git rebase origin/${this.platformKit.platformConfig.baseBranchName}`,
147+
{ stdio: "inherit" },
148+
);
124149
this.ora.succeed("Successfully rebased branch");
125150
} catch (error) {
126151
this.ora.warn("Rebase failed, falling back to alternative sync method");
@@ -129,15 +154,22 @@ export class PullRequestFlow extends InBranchFlow {
129154
execSync("git rebase --abort", { stdio: "inherit" });
130155
this.ora.succeed("Aborted failed rebase");
131156

132-
this.ora.start(`Resetting to ${this.platformKit.platformConfig.baseBranchName}`);
133-
execSync(`git reset --hard origin/${this.platformKit.platformConfig.baseBranchName}`, { stdio: "inherit" });
134-
this.ora.succeed(`Reset to ${this.platformKit.platformConfig.baseBranchName}`);
157+
this.ora.start(
158+
`Resetting to ${this.platformKit.platformConfig.baseBranchName}`,
159+
);
160+
execSync(
161+
`git reset --hard origin/${this.platformKit.platformConfig.baseBranchName}`,
162+
{ stdio: "inherit" },
163+
);
164+
this.ora.succeed(
165+
`Reset to ${this.platformKit.platformConfig.baseBranchName}`,
166+
);
135167

136168
this.ora.start("Restoring target files");
137169
const targetFiles = ["i18n.lock"];
138170
const targetFileNames = execSync(
139171
`npx lingo.dev@latest show files --target ${this.platformKit.platformConfig.baseBranchName}`,
140-
{ encoding: "utf8" }
172+
{ encoding: "utf8" },
141173
)
142174
.split("\n")
143175
.filter(Boolean);
@@ -160,9 +192,12 @@ export class PullRequestFlow extends InBranchFlow {
160192
const hasChanges = this.checkCommitableChanges();
161193
if (hasChanges) {
162194
execSync("git add .", { stdio: "inherit" });
163-
execSync(`git commit -m "chore: sync with ${this.platformKit.platformConfig.baseBranchName}"`, {
164-
stdio: "inherit",
165-
});
195+
execSync(
196+
`git commit -m "chore: sync with ${this.platformKit.platformConfig.baseBranchName}"`,
197+
{
198+
stdio: "inherit",
199+
},
200+
);
166201
this.ora.succeed("Committed additional changes");
167202
} else {
168203
this.ora.succeed("No changes to commit");

packages/cli/src/cli/cmd/ci.ts renamed to packages/cli/src/cli/cmd/ci/index.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Command } from "interactive-commander";
2-
import { getSettings } from "../utils/settings";
3-
import { createAuthenticator } from "../utils/auth";
4-
import main from "../../action/src/main";
2+
import createOra from "ora";
3+
import { getSettings } from "../../utils/settings";
4+
import { createAuthenticator } from "../../utils/auth";
5+
import { IIntegrationFlow } from "./flows/_base";
6+
import { PullRequestFlow } from "./flows/pull-request";
7+
import { InBranchFlow } from "./flows/in-branch";
8+
import { getPlatformKit } from "./platforms";
59

610
interface CIOptions {
711
pullRequest?: boolean;
@@ -43,13 +47,41 @@ export default new Command()
4347
const env = {
4448
LINGODOTDEV_API_KEY: settings.auth.apiKey,
4549
LINGODOTDEV_PULL_REQUEST: options.pullRequest?.toString() || "false",
46-
...(options.commitMessage && { LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage }),
47-
...(options.pullRequestTitle && { LINGODOTDEV_PULL_REQUEST_TITLE: options.pullRequestTitle }),
48-
...(options.workingDirectory && { LINGODOTDEV_WORKING_DIRECTORY: options.workingDirectory }),
49-
...(options.processOwnCommits && { LINGODOTDEV_PROCESS_OWN_COMMITS: options.processOwnCommits.toString() }),
50+
...(options.commitMessage && {
51+
LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage,
52+
}),
53+
...(options.pullRequestTitle && {
54+
LINGODOTDEV_PULL_REQUEST_TITLE: options.pullRequestTitle,
55+
}),
56+
...(options.workingDirectory && {
57+
LINGODOTDEV_WORKING_DIRECTORY: options.workingDirectory,
58+
}),
59+
...(options.processOwnCommits && {
60+
LINGODOTDEV_PROCESS_OWN_COMMITS: options.processOwnCommits.toString(),
61+
}),
5062
};
5163

5264
process.env = { ...process.env, ...env };
5365

54-
main();
66+
const ora = createOra();
67+
const platformKit = getPlatformKit();
68+
const { isPullRequestMode } = platformKit.config;
69+
70+
ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
71+
72+
const flow: IIntegrationFlow = isPullRequestMode
73+
? new PullRequestFlow(ora, platformKit)
74+
: new InBranchFlow(ora, platformKit);
75+
76+
const canRun = await flow.preRun?.();
77+
if (canRun === false) {
78+
return;
79+
}
80+
81+
const hasChanges = await flow.run();
82+
if (!hasChanges) {
83+
return;
84+
}
85+
86+
await flow.postRun?.();
5587
});

0 commit comments

Comments
 (0)