From 620227307d29b135d559041760d90f22f645883f Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Sun, 19 Apr 2026 18:20:19 +0530 Subject: [PATCH] release: v4.3.0 - fix Windows SmartScreen blocking, add signing support - Remove signAndEditExecutable:false so code signing works properly - Add legalTrademarks and copyright metadata to build config - Add publisherName via build.copyright (embedded in PE resources) - Create scripts/create-selfsigned-cert.ps1 for local dev signing - Update release.yml: build on windows-latest runner (not Wine), auto-sign when CSC_LINK_BASE64/CSC_KEY_PASSWORD secrets present, fall back to unsigned otherwise - Add lint step to ci.yml (Phase 4.3 plan gap) - Add .vscode/launch.json debug configs (Phase 4.3 plan gap) - Fix .gitignore: exclude *.pfx/*.p12 cert files, track launch.json, fix concatenated agents.md/coverage/ lines Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 3 ++ .github/workflows/release.yml | 34 ++++++++++++----- .gitignore | 10 ++++- .vscode/launch.json | 48 ++++++++++++++++++++++++ package.json | 9 +++-- scripts/create-selfsigned-cert.ps1 | 59 ++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 scripts/create-selfsigned-cert.ps1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b82b5f1..d008622 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,3 +23,6 @@ jobs: - name: Run tests run: npm test + + - name: Run linter + run: npm run lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60d497a..96bbcda 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: retention-days: 5 build-windows: - runs-on: ubuntu-latest + runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -53,17 +53,32 @@ jobs: node-version: 20 cache: npm - - name: Install Wine and NSIS - run: | - sudo dpkg --add-architecture i386 - sudo apt-get update - sudo apt-get install -y wine64 wine32 nsis - - name: Install dependencies run: npm ci - - name: Build Windows packages - run: npm run build:win + - name: Run tests + run: npm test + + - name: Decode certificate (if available) + if: ${{ secrets.CSC_LINK_BASE64 != '' }} + shell: pwsh + run: | + $bytes = [Convert]::FromBase64String("${{ secrets.CSC_LINK_BASE64 }}") + [IO.File]::WriteAllBytes("${{ github.workspace }}\code-signing-cert.pfx", $bytes) + echo "CERT_AVAILABLE=true" >> $env:GITHUB_ENV + + - name: Build Windows packages (signed) + if: ${{ env.CERT_AVAILABLE == 'true' }} + env: + CSC_LINK: code-signing-cert.pfx + CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + run: npm run build:win-signed + + - name: Build Windows packages (unsigned) + if: ${{ env.CERT_AVAILABLE != 'true' }} + env: + CSC_IDENTITY_AUTO_DISCOVERY: false + run: npm run build:win-unsigned - name: Upload Windows artifacts uses: actions/upload-artifact@v4 @@ -72,6 +87,7 @@ jobs: path: | dist/*.exe dist/*-win.zip + dist/*.zip retention-days: 5 release: diff --git a/.gitignore b/.gitignore index d142a98..cc1a981 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,8 @@ Thumbs.db *.swp *.swo *~ -.vscode/ +.vscode/* +!.vscode/launch.json .idea/ *.iml out/ @@ -17,6 +18,10 @@ out/ .electron/ package-lock.json +# Code signing certificates — never commit private keys +*.pfx +*.p12 + # Screenshots and temp files *.png.bak Screen.png @@ -33,4 +38,5 @@ pdf\ modal.png # Claude/AI development files .claude/ CLAUDE.md -agents.mdcoverage/ +agents.md +coverage/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5760f66 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,48 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Main Process", + "type": "node", + "request": "launch", + "cwd": "${workspaceFolder}", + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", + "windows": { + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd" + }, + "args": ["."], + "outputCapture": "std", + "env": { + "NODE_ENV": "development" + } + }, + { + "name": "Debug Renderer Process", + "type": "chrome", + "request": "attach", + "port": 9222, + "webRoot": "${workspaceFolder}/src", + "timeout": 30000 + }, + { + "name": "Debug Main + Renderer", + "type": "node", + "request": "launch", + "cwd": "${workspaceFolder}", + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", + "windows": { + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd" + }, + "args": [".", "--remote-debugging-port=9222"], + "outputCapture": "std", + "env": { + "NODE_ENV": "development" + }, + "serverReadyAction": { + "pattern": "listening on port ([0-9]+)", + "uriFormat": "http://localhost:%s", + "action": "debugWithChrome" + } + } + ] +} diff --git a/package.json b/package.json index d0bddc6..af25071 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "markdown-converter", - "version": "4.2.0", + "version": "4.3.0", "description": "Professional Markdown editor and universal file converter with PDF editing, batch processing, and syntax highlighting", "main": "src/main.js", "scripts": { @@ -14,8 +14,9 @@ "format:check": "prettier --check src tests", "build": "electron-builder", "build:win": "electron-builder --win", - "build:win-signed": "cross-env CSC_LINK=code-signing-cert.pfx CSC_KEY_PASSWORD=%CSC_KEY_PASSWORD% electron-builder --win", + "build:win-signed": "cross-env CSC_LINK=code-signing-cert.pfx electron-builder --win", "build:win-unsigned": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --win", + "create-cert": "powershell -ExecutionPolicy Bypass -File scripts/create-selfsigned-cert.ps1", "build:mac": "electron-builder --mac", "build:linux": "electron-builder --linux", "build:local": "electron-builder --linux --win", @@ -96,6 +97,7 @@ "build": { "appId": "com.concreteinfo.markdownconverter", "productName": "MarkdownConverter", + "copyright": "Copyright (C) 2024-2025 ConcreteInfo", "directories": { "output": "dist" }, @@ -157,7 +159,8 @@ ], "artifactName": "${productName}-${version}-${arch}.${ext}", "requestedExecutionLevel": "asInvoker", - "signAndEditExecutable": false + "legalTrademarks": "Copyright (C) 2024-2025 ConcreteInfo", + "verifyUpdateCodeSignature": false }, "nsis": { "oneClick": false, diff --git a/scripts/create-selfsigned-cert.ps1 b/scripts/create-selfsigned-cert.ps1 new file mode 100644 index 0000000..98590e7 --- /dev/null +++ b/scripts/create-selfsigned-cert.ps1 @@ -0,0 +1,59 @@ +# create-selfsigned-cert.ps1 +# Generates a self-signed code-signing certificate for local/development builds. +# +# Usage: +# powershell -ExecutionPolicy Bypass -File scripts/create-selfsigned-cert.ps1 +# npm run create-cert +# +# Then build with: +# $env:CSC_LINK="code-signing-cert.pfx"; $env:CSC_KEY_PASSWORD="YourPassword"; npm run build:win-signed +# +# NOTE: Self-signed certificates will still show a SmartScreen warning for end users. +# For production releases, obtain an OV or EV certificate from a trusted CA +# (DigiCert, Sectigo, Certum, etc.). EV certificates bypass SmartScreen immediately. +# Open-source projects can apply for free signing at https://signpath.io/ + +param( + [string]$CertPassword = "MarkdownConverter2025", + [string]$OutputFile = "code-signing-cert.pfx", + [string]$Subject = "CN=ConcreteInfo, O=ConcreteInfo, L=India, C=IN" +) + +Write-Host "Creating self-signed code-signing certificate..." -ForegroundColor Cyan + +# Create the certificate in the current user's certificate store +$cert = New-SelfSignedCertificate ` + -Type CodeSigningCert ` + -Subject $Subject ` + -CertStoreLocation "Cert:\CurrentUser\My" ` + -NotAfter (Get-Date).AddYears(3) ` + -HashAlgorithm SHA256 ` + -KeyLength 4096 ` + -KeyUsage DigitalSignature + +if (-not $cert) { + Write-Error "Failed to create certificate." + exit 1 +} + +Write-Host "Certificate created: $($cert.Thumbprint)" -ForegroundColor Green + +# Export to PFX +$securePassword = ConvertTo-SecureString -String $CertPassword -Force -AsPlainText +$exportPath = Join-Path (Get-Location) $OutputFile + +Export-PfxCertificate -Cert $cert -FilePath $exportPath -Password $securePassword | Out-Null + +if (Test-Path $exportPath) { + Write-Host "Certificate exported to: $exportPath" -ForegroundColor Green + Write-Host "" + Write-Host "To build a signed release:" -ForegroundColor Yellow + Write-Host ' $env:CSC_LINK="code-signing-cert.pfx"' -ForegroundColor White + Write-Host " `$env:CSC_KEY_PASSWORD=`"$CertPassword`"" -ForegroundColor White + Write-Host " npm run build:win-signed" -ForegroundColor White + Write-Host "" + Write-Host "IMPORTANT: Add code-signing-cert.pfx to .gitignore!" -ForegroundColor Red +} else { + Write-Error "Export failed." + exit 1 +}