Skip to content

Commit 81b2447

Browse files
authored
feat(cli): add "ci" command (#599)
Execute CI/CD action via `npx lingo.dev ci`
1 parent a4617e0 commit 81b2447

File tree

12 files changed

+113
-32
lines changed

12 files changed

+113
-32
lines changed

.changeset/rich-eyes-march.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" command

action/src/index.ts

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,3 @@
1-
import createOra from "ora";
1+
import main from "./main.js";
22

3-
import { IIntegrationFlow } from "./flows/_base.js";
4-
import { PullRequestFlow } from "./flows/pull-request.js";
5-
import { InBranchFlow } from "./flows/in-branch.js";
6-
import { getPlatformKit } from "./platforms/index.js";
7-
8-
(async function main() {
9-
const ora = createOra();
10-
const platformKit = getPlatformKit();
11-
const { isPullRequestMode } = platformKit.config;
12-
13-
ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
14-
15-
const flow: IIntegrationFlow = isPullRequestMode
16-
? new PullRequestFlow(ora, platformKit)
17-
: new InBranchFlow(ora, platformKit);
18-
19-
const canRun = await flow.preRun?.();
20-
if (canRun === false) {
21-
return;
22-
}
23-
24-
const hasChanges = await flow.run();
25-
if (!hasChanges) {
26-
return;
27-
}
28-
29-
await flow.postRun?.();
30-
})();
3+
main();

action/src/main.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
declare module "@lingo.dev/_action" {
2+
export default function main(): Promise<void>;
3+
}

action/src/main.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import createOra from "ora";
2+
3+
import { IIntegrationFlow } from "./flows/_base.js";
4+
import { PullRequestFlow } from "./flows/pull-request.js";
5+
import { InBranchFlow } from "./flows/in-branch.js";
6+
import { getPlatformKit } from "./platforms/index.js";
7+
8+
export default async function main() {
9+
const ora = createOra();
10+
const platformKit = getPlatformKit();
11+
const { isPullRequestMode } = platformKit.config;
12+
13+
ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
14+
15+
const flow: IIntegrationFlow = isPullRequestMode
16+
? new PullRequestFlow(ora, platformKit)
17+
: new InBranchFlow(ora, platformKit);
18+
19+
const canRun = await flow.preRun?.();
20+
if (canRun === false) {
21+
return;
22+
}
23+
24+
const hasChanges = await flow.run();
25+
if (!hasChanges) {
26+
return;
27+
}
28+
29+
await flow.postRun?.();
30+
}

action/src/platforms/bitbucket.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface BitbucketConfig {
1515
export class BitbucketPlatformKit extends PlatformKit<BitbucketConfig> {
1616
private _bb?: ReturnType<typeof Bitbucket>;
1717

18-
get bb() {
18+
private get bb() {
1919
if (!this._bb) {
2020
this._bb = new Bitbucket({
2121
auth: { token: this.platformConfig.bbToken || "" },

action/src/platforms/github.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { execSync } from "child_process";
77
export class GitHubPlatformKit extends PlatformKit {
88
private _octokit?: Octokit;
99

10-
get octokit() {
10+
private get octokit(): Octokit {
1111
if (!this._octokit) {
1212
this._octokit = new Octokit({ auth: this.platformConfig.ghToken });
1313
}

action/src/platforms/gitlab.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export class GitlabPlatformKit extends PlatformKit {
1515
process.chdir(this.platformConfig.projectDir);
1616
}
1717

18-
get gitlab() {
18+
private get gitlab(): InstanceType<typeof Gitlab> {
1919
if (!this._gitlab) {
2020
this._gitlab = new Gitlab({
2121
token: this.platformConfig.glToken || "",

packages/cli/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@
5858
"license": "Apache-2.0",
5959
"dependencies": {
6060
"@datocms/cma-client-node": "^3.4.0",
61+
"@gitbeaker/rest": "^39.34.3",
6162
"@inquirer/prompts": "^7.2.3",
6263
"@lingo.dev/_sdk": "workspace:*",
6364
"@lingo.dev/_spec": "workspace:*",
6465
"@modelcontextprotocol/sdk": "^1.5.0",
6566
"@paralleldrive/cuid2": "^2.2.2",
67+
"bitbucket": "^2.12.0",
6668
"chalk": "^5.4.1",
6769
"cors": "^2.8.5",
6870
"csv-parse": "^5.6.0",
@@ -92,6 +94,7 @@
9294
"marked": "^15.0.6",
9395
"node-webvtt": "^1.9.4",
9496
"object-hash": "^3.0.0",
97+
"octokit": "^4.0.2",
9598
"open": "^10.1.0",
9699
"ora": "^8.1.1",
97100
"p-limit": "^6.2.0",

packages/cli/src/action

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../action

packages/cli/src/cli/cmd/ci.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { Command } from "interactive-commander";
2+
import { getSettings } from "../utils/settings";
3+
import { createAuthenticator } from "../utils/auth";
4+
import main from "../../action/src/main";
5+
6+
interface CIOptions {
7+
pullRequest?: boolean;
8+
commitMessage?: string;
9+
pullRequestTitle?: string;
10+
workingDirectory?: string;
11+
processOwnCommits?: boolean;
12+
}
13+
14+
export default new Command()
15+
.command("ci")
16+
.description("Run Lingo.dev CI/CD action")
17+
.helpOption("-h, --help", "Show help")
18+
.option("--pull-request", "Create a pull request with the changes", false)
19+
.option("--commit-message <message>", "Commit message")
20+
.option("--pull-request-title <title>", "Pull request title")
21+
.option("--working-directory <dir>", "Working directory")
22+
.option("--process-own-commits", "Process commits made by this action", false)
23+
.action(async (options: CIOptions, program) => {
24+
const apiKey = program.args[0];
25+
const settings = getSettings(apiKey);
26+
27+
if (!settings.auth.apiKey) {
28+
console.error("No API key provided");
29+
return;
30+
}
31+
32+
const authenticator = createAuthenticator({
33+
apiUrl: settings.auth.apiUrl,
34+
apiKey: settings.auth.apiKey,
35+
});
36+
const auth = await authenticator.whoami();
37+
38+
if (!auth) {
39+
console.error("Not authenticated");
40+
return;
41+
}
42+
43+
const env = {
44+
LINGODOTDEV_API_KEY: settings.auth.apiKey,
45+
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+
};
51+
52+
process.env = { ...process.env, ...env };
53+
54+
main();
55+
});

0 commit comments

Comments
 (0)