Skip to content

Commit ef9fcbd

Browse files
authored
feat: add gpg support (#1954)
* feat: add GPG commit signing support to GitHub Action * feat: add GPG signing test workflow * chore: remove unnecessary console log from CI command * chore: remove GPG signing test workflow from CI
1 parent 09ac536 commit ef9fcbd

File tree

6 files changed

+69
-5
lines changed

6 files changed

+69
-5
lines changed

.changeset/public-nails-tease.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
"lingo.dev": minor
3+
---
4+
5+
feat: add GPG commit signing support to GitHub Action
6+
7+
- Added `gpg-sign` input to action.yml for enabling GPG commit signing
8+
- Added `--gpg-sign` CLI option for the `ci` command
9+
- Added preflight check to verify GPG signing key is configured before committing
10+
- Commits are signed with `-S` flag when GPG signing is enabled
11+
- Works with both in-branch and pull-request modes
12+
13+
Usage:
14+
```yaml
15+
- uses: crazy-max/ghaction-import-gpg@v6
16+
with:
17+
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
18+
git_user_signingkey: true
19+
git_commit_gpgsign: true
20+
21+
- uses: lingodotdev/lingo.dev@main
22+
with:
23+
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
24+
gpg-sign: true
25+
```

action.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ runs:
2020
--commit-author-email "${{ inputs.commit-author-email }}" \
2121
--working-directory "${{ inputs.working-directory }}" \
2222
--process-own-commits "${{ inputs.process-own-commits }}" \
23-
--parallel ${{ inputs.parallel }}
23+
--parallel ${{ inputs.parallel }} \
24+
--gpg-sign "${{ inputs.gpg-sign }}"
2425
shell: bash
2526
inputs:
2627
version:
@@ -62,3 +63,7 @@ inputs:
6263
description: "Run in parallel mode"
6364
default: false
6465
required: false
66+
gpg-sign:
67+
description: "Sign commits with GPG. Requires GPG key to be configured (e.g., via crazy-max/ghaction-import-gpg)"
68+
default: false
69+
required: false

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ export class InBranchFlow extends IntegrationFlow {
3333
this.ora.start("Committing changes");
3434
execSync(`git add .`, { stdio: "inherit" });
3535
execSync(`git status --porcelain`, { stdio: "inherit" });
36+
const signFlag = this.platformKit.config.gpgSign ? "-S " : "";
3637
execSync(
37-
`git commit -m ${escapeShellArg(
38+
`git commit ${signFlag}-m ${escapeShellArg(
3839
this.platformKit.config.commitMessage,
3940
)} --no-verify`,
4041
{
@@ -101,6 +102,26 @@ export class InBranchFlow extends IntegrationFlow {
101102
execSync(`git config user.name "${gitConfig.userName}"`);
102103
execSync(`git config user.email "${gitConfig.userEmail}"`);
103104

105+
// Configure GPG signing if enabled
106+
if (this.platformKit.config.gpgSign) {
107+
// Preflight check: verify signing key is configured
108+
try {
109+
const signingKey = execSync(`git config user.signingkey`, {
110+
encoding: "utf8",
111+
}).trim();
112+
if (!signingKey) {
113+
throw new Error("No signing key configured");
114+
}
115+
} catch {
116+
throw new Error(
117+
"GPG signing is enabled but no signing key is configured. " +
118+
"Import a GPG key (e.g., using crazy-max/ghaction-import-gpg) before running this action, " +
119+
"or set gpg-sign to false.",
120+
);
121+
}
122+
execSync(`git config commit.gpgsign true`);
123+
}
124+
104125
// perform platform-specific configuration before fetching or pushing to the remote
105126
this.platformKit?.gitConfig();
106127

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,9 @@ export class PullRequestFlow extends InBranchFlow {
198198
const hasChanges = this.checkCommitableChanges();
199199
if (hasChanges) {
200200
execSync("git add .", { stdio: "inherit" });
201+
const signFlag = this.platformKit.config.gpgSign ? "-S " : "";
201202
execSync(
202-
`git commit -m "chore: sync with ${this.platformKit.platformConfig.baseBranchName}" --no-verify`,
203+
`git commit ${signFlag}-m "chore: sync with ${this.platformKit.platformConfig.baseBranchName}" --no-verify`,
203204
{
204205
stdio: "inherit",
205206
},

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface CIOptions {
1818
commitAuthorEmail?: string;
1919
workingDirectory?: string;
2020
processOwnCommits?: boolean;
21+
gpgSign?: boolean;
2122
}
2223

2324
export default new Command()
@@ -63,11 +64,14 @@ export default new Command()
6364
"Allow processing commits made by this CI user (bypasses infinite loop prevention)",
6465
parseBooleanArg,
6566
)
67+
.option(
68+
"--gpg-sign [boolean]",
69+
"Sign commits with GPG. Requires GPG to be configured in the environment",
70+
parseBooleanArg,
71+
)
6672
.action(async (options: CIOptions) => {
6773
const settings = getSettings(options.apiKey);
6874

69-
console.log(options);
70-
7175
if (!settings.auth.apiKey) {
7276
console.error("No API key provided");
7377
return;
@@ -105,6 +109,9 @@ export default new Command()
105109
...(options.processOwnCommits && {
106110
LINGODOTDEV_PROCESS_OWN_COMMITS: options.processOwnCommits.toString(),
107111
}),
112+
...(options.gpgSign && {
113+
LINGODOTDEV_GPG_SIGN: options.gpgSign.toString(),
114+
}),
108115
};
109116

110117
process.env = { ...process.env, ...env };

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ export abstract class PlatformKit<
6161
(val) => val === "true" || val === true,
6262
Z.boolean(),
6363
).optional(),
64+
LINGODOTDEV_GPG_SIGN: Z.preprocess(
65+
(val) => val === "true" || val === true,
66+
Z.boolean(),
67+
).optional(),
6468
}).parse(process.env);
6569

6670
return {
@@ -73,6 +77,7 @@ export abstract class PlatformKit<
7377
env.LINGODOTDEV_COMMIT_AUTHOR_EMAIL || "support@lingo.dev",
7478
workingDir: env.LINGODOTDEV_WORKING_DIRECTORY || ".",
7579
processOwnCommits: env.LINGODOTDEV_PROCESS_OWN_COMMITS || false,
80+
gpgSign: env.LINGODOTDEV_GPG_SIGN || false,
7681
};
7782
}
7883
}

0 commit comments

Comments
 (0)