Skip to content

Commit 035e16c

Browse files
Add scripts for updating executable metadata and signing
- Created `debug-rcedit.mjs` for testing rcedit functionality. - Implemented `set-icon.mjs` to update executable metadata and optionally set an icon from assets. - Added `sign-exe.ps1` PowerShell script to sign the executable with a digital certificate.
1 parent afb5925 commit 035e16c

File tree

10 files changed

+201
-0
lines changed

10 files changed

+201
-0
lines changed

assets/README.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Please place your application icon here and name it "logo.ico".
2+
It will be used for the executable and the installer.

assets/logo.ico

136 KB
Binary file not shown.

assets/logo.png

196 KB
Loading

installer/cloudsqlctl.iss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define MyAppPublisher "Kinin Code"
66
#define MyAppURL "https://github.com/Kinin-Code-Offical/cloudsqlctl"
77
#define MyAppExeName "cloudsqlctl.exe"
8+
#define MyAppIcon "..\assets\logo.ico"
89

910
[Setup]
1011
AppId={{8A4B2C1D-E3F4-5678-9012-3456789ABCDE}
@@ -15,6 +16,9 @@ AppPublisherURL={#MyAppURL}
1516
AppSupportURL={#MyAppURL}
1617
AppUpdatesURL={#MyAppURL}
1718
DefaultDirName={autopf}\{#MyAppName}
19+
#ifexist MyAppIcon
20+
SetupIconFile={#MyAppIcon}
21+
#endif
1822
DisableProgramGroupPage=yes
1923
PrivilegesRequired=admin
2024
OutputDir=..\dist

package-lock.json

Lines changed: 91 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"jest": "30.2.0",
5757
"postject": "1.0.0-alpha.6",
5858
"prettier": "^3.2.5",
59+
"rcedit": "5.0.2",
5960
"ts-jest": "^29.1.2",
6061
"ts-node": "10.9.2",
6162
"tsup": "^8.0.2",

tools/build-sea.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,12 @@ npx postject dist/cloudsqlctl-base.exe NODE_SEA_BLOB dist/sea-prep.blob --sentin
4040
Write-Host "Finalizing..."
4141
Move-Item -Path "dist/cloudsqlctl-base.exe" -Destination "bin/cloudsqlctl.exe" -Force
4242

43+
# 7. Set Icon (if available)
44+
Write-Host "Setting icon..."
45+
node tools/set-icon.mjs
46+
47+
# 8. Sign Executable (Optional)
48+
Write-Host "Attempting to sign executable..."
49+
./tools/sign-exe.ps1
50+
4351
Write-Host "Build complete: bin/cloudsqlctl.exe"

tools/debug-rcedit.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { createRequire } from 'module';
2+
const require = createRequire(import.meta.url);
3+
const rcedit = require('rcedit');
4+
console.log(rcedit);

tools/set-icon.mjs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import path from 'path';
2+
import fs from 'fs';
3+
import { fileURLToPath } from 'url';
4+
import { rcedit } from 'rcedit';
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
const __dirname = path.dirname(__filename);
8+
9+
// Read package.json
10+
const packageJsonPath = path.resolve(__dirname, '../package.json');
11+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
12+
const { version } = packageJson;
13+
14+
const exePath = path.resolve(__dirname, '../bin/cloudsqlctl.exe');
15+
const iconPath = path.resolve(__dirname, '../assets/logo.ico');
16+
17+
async function main() {
18+
// Icon is optional, but metadata is mandatory
19+
const hasIcon = fs.existsSync(iconPath);
20+
if (!hasIcon) {
21+
console.log(
22+
'No icon found at assets/logo.ico. Skipping icon update, but will update metadata.',
23+
);
24+
}
25+
26+
if (!fs.existsSync(exePath)) {
27+
console.error(`Executable not found at ${exePath}`);
28+
process.exit(1);
29+
}
30+
31+
console.log(`Updating executable metadata (Version: ${version})...`);
32+
33+
const options = {
34+
'version-string': {
35+
CompanyName: 'Kinin Code',
36+
FileDescription: 'CloudSQLCTL - Google Cloud SQL Proxy Manager',
37+
FileVersion: version,
38+
InternalName: 'cloudsqlctl',
39+
LegalCopyright: 'Copyright (c) 2025 Kinin Code. All rights reserved.',
40+
OriginalFilename: 'cloudsqlctl.exe',
41+
ProductName: 'CloudSQLCTL',
42+
ProductVersion: version,
43+
},
44+
'file-version': version,
45+
'product-version': version,
46+
};
47+
48+
if (hasIcon) {
49+
options.icon = iconPath;
50+
}
51+
52+
try {
53+
await rcedit(exePath, options);
54+
console.log('Executable metadata updated successfully.');
55+
} catch (error) {
56+
console.error('Error updating executable resources:', error);
57+
process.exit(1);
58+
}
59+
}
60+
61+
main();

tools/sign-exe.ps1

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
param(
2+
[string]$ExePath = "bin\cloudsqlctl.exe",
3+
[string]$CertPath = "$env:CLOUDSQLCTL_SIGN_CERT",
4+
[SecureString]$CertPassword = "$env:CLOUDSQLCTL_SIGN_PWD"
5+
)
6+
7+
$ErrorActionPreference = "Stop"
8+
9+
if (-not (Test-Path $ExePath)) {
10+
Write-Warning "Executable not found at $ExePath. Skipping signing."
11+
exit 0
12+
}
13+
14+
if (-not $CertPath -or -not (Test-Path $CertPath)) {
15+
Write-Warning "Signing certificate not found (env:CLOUDSQLCTL_SIGN_CERT). Skipping digital signature."
16+
Write-Host "To enable signing, set CLOUDSQLCTL_SIGN_CERT to the path of your .pfx file."
17+
exit 0
18+
}
19+
20+
Write-Host "Signing $ExePath with certificate $CertPath..."
21+
22+
try {
23+
$cert = Get-PfxCertificate -FilePath $CertPath
24+
Set-AuthenticodeSignature -FilePath $ExePath -Certificate $cert -TimestampServer "http://timestamp.digicert.com"
25+
Write-Host "Successfully signed $ExePath"
26+
}
27+
catch {
28+
Write-Error "Failed to sign executable: $_"
29+
exit 1
30+
}

0 commit comments

Comments
 (0)