fix(jetbrains): use file-based signing secrets for bundled publish workflow

Passing the JETBRAINS_CERTIFICATE_CHAIN / JETBRAINS_PRIVATE_KEY multiline
secret content directly as certificateChain/privateKey Gradle properties
gets mishandled by the zip-signer CLI when signPlugin and
verifyPluginSignature run as separate Gradle invocations (#12567), causing
verifyPluginSignature to fail with 'Invalid argument: ***' as the masked
multiline content is split into extra CLI args.

Mirror script/build-version.sh: write the certificate chain and private
key to temp files under $RUNNER_TEMP and wire
certificateChainFile/privateKeyFile (file-based) into the intellij
signing extension instead of certificateChain/privateKey (raw content).

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
This commit is contained in:
kirillk
2026-07-27 15:56:30 +00:00
parent 714b987c48
commit 2da0cac53f
2 changed files with 32 additions and 4 deletions
@@ -142,6 +142,22 @@ jobs:
JETBRAINS_PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
JETBRAINS_PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
- name: Write signing secrets to temp files
run: |
dir="$RUNNER_TEMP/jetbrains-signing"
mkdir -m 700 -p "$dir"
chain="$dir/certificate-chain.pem"
key="$dir/private-key.pem"
umask 077
printf '%s' "$JETBRAINS_CERTIFICATE_CHAIN" > "$chain"
printf '%s' "$JETBRAINS_PRIVATE_KEY" > "$key"
chmod 600 "$chain" "$key"
echo "JETBRAINS_CERTIFICATE_CHAIN_FILE=$chain" >> "$GITHUB_ENV"
echo "JETBRAINS_PRIVATE_KEY_FILE=$key" >> "$GITHUB_ENV"
env:
JETBRAINS_CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
JETBRAINS_PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
- name: Build signed bundled plugin
working-directory: packages/kilo-jetbrains
run: |
@@ -152,6 +168,9 @@ jobs:
-Pkilo.cli.bundled=true
)
# signPlugin and verifyPluginSignature run as separate Gradle invocations (see #12567)
# so the JETBRAINS_CERTIFICATE_CHAIN_FILE / JETBRAINS_PRIVATE_KEY_FILE env vars set in
# the previous step (rather than raw multiline secret content) must be present for both.
./gradlew clean buildPlugin "${args[@]}"
./gradlew signPlugin "${args[@]}"
./gradlew verifyPluginSignature "${args[@]}"
@@ -161,10 +180,12 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
VERSION: ${{ needs.validate.outputs.version }}
CHANNEL: ${{ needs.validate.outputs.channel }}
JETBRAINS_CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
JETBRAINS_PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
JETBRAINS_PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
- name: Remove signing secret temp files
if: always()
run: rm -rf "$RUNNER_TEMP/jetbrains-signing"
- name: Resolve bundled archive
id: archive
run: |
+9 -2
View File
@@ -207,8 +207,15 @@ intellijPlatform {
}
signing {
certificateChain = providers.environmentVariable("JETBRAINS_CERTIFICATE_CHAIN")
privateKey = providers.environmentVariable("JETBRAINS_PRIVATE_KEY")
// File-based inputs are preferred over raw content: certificateChain/privateKey take
// precedence over certificateChainFile/privateKeyFile in the IntelliJ Platform Gradle
// plugin, and passing multiline PEM content straight through as a certificateChain/
// privateKey value can get mishandled as extra CLI arguments by the zip-signer CLI when
// signPlugin/verifyPluginSignature run as separate Gradle invocations. Both CI
// (.github/workflows/publish-jetbrains-bundled.yml) and local releases
// (script/build-version.sh) write the secrets to files and export the *_FILE variables.
certificateChainFile.fileProvider(providers.environmentVariable("JETBRAINS_CERTIFICATE_CHAIN_FILE").map { file(it) })
privateKeyFile.fileProvider(providers.environmentVariable("JETBRAINS_PRIVATE_KEY_FILE").map { file(it) })
password = providers.environmentVariable("JETBRAINS_PRIVATE_KEY_PASSWORD")
}