Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 169 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,42 +1,205 @@
# CI workflow for PIME
# This workflow is split into two jobs:
# 1️⃣ **build** – runs on every push / PR. It builds the project, runs tests,
# uploads unsigned artifacts, and performs test‑only signing (no manual approval).
# 2️⃣ **release** – runs only for tag pushes. It requires the `production`
# environment (manual approval in GitHub) and performs the production signing
# of both binaries and the installer, then creates a GitHub Release.

name: Build

on:
push:
branches: ['**']
tags: ['v*']
pull_request:
branches: [main]

jobs:
# ---------------------------------------------------------------------
# Build job – runs on every push/PR. Includes test signing only.
# ---------------------------------------------------------------------
build:
runs-on: windows-latest
runs-on: windows-2025
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v3
with:
submodules: 'true'

- name: Use Node.js 21.x
uses: actions/setup-node@v4
with:
node-version: 21.x

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: i686-pc-windows-msvc

- name: Run Rust tests
run: |
cd PIMELauncher
cargo test --verbose

- name: Use Install NSIS
uses: repolevedavaj/install-nsis@v1.2.0
with:
nsis-version: 3.08

- name: Run build.bat
env:
Rust_COMPILER: ${{ env.CARGO_HOME }}\bin\rustc.exe
Rust_COMPILER: ${{ env.CARGO_HOME }}\\bin\\rustc.exe
run: |
.\\build.bat

# ---------------------------------------------------------------
# Upload unsigned binaries – needed for both test and release signing.
# ---------------------------------------------------------------
- name: Upload unsigned binaries
id: upload-unsigned-binaries
uses: actions/upload-artifact@v7
with:
name: unsigned-binaries
path: |
build/PIMELauncher/PIMELauncher.exe
build/PIMETextService/Release/PIMETextService.dll
build64/PIMETextService/Release/PIMETextService.dll
build_arm64/PIMETextService/Release/PIMETextService.dll

# ---------------------------------------------------------------
# ----- Test signing (runs on every non‑tag commit) -----
# Uses the test certificate and does NOT require manual approval.
# ---------------------------------------------------------------
- name: Sign binaries (test)
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '44e7ac31-01b7-47df-8a58-44125a7d21b0'
project-slug: 'PIME'
signing-policy-slug: 'test-signing'
artifact-configuration-slug: 'binaries-zip'
github-artifact-id: '${{ steps.upload-unsigned-binaries.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'signed-binaries'

# ---------------------------------------------------------------
# Upload the signed binaries as an artifact so the release job can use them.
# This step runs on every build (both test and release paths) because the
# `signpath` action always writes to the `signed-binaries` directory.
# ---------------------------------------------------------------
- name: Upload signed binaries
if: always() # ensure the artifact exists even if signing was skipped
uses: actions/upload-artifact@v7
with:
name: signed-binaries
path: signed-binaries/**

# ---------------------------------------------------------------
# Replace binaries with the signed versions (test‑signing case).
# This step runs only when we have signed binaries (i.e., after test signing).
# ---------------------------------------------------------------
- name: Replace binaries with signed versions
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
run: |
.\build.bat
copy signed-binaries\build\PIMELauncher\PIMELauncher.exe build\PIMELauncher\PIMELauncher.exe
copy signed-binaries\build\PIMETextService\Release\PIMETextService.dll build\PIMETextService\Release\PIMETextService.dll
copy signed-binaries\build64\PIMETextService\Release\PIMETextService.dll build64\PIMETextService\Release\PIMETextService.dll
copy signed-binaries\build_arm64\PIMETextService\Release\PIMETextService.dll build_arm64\PIMETextService\Release\PIMETextService.dll

# ---------------------------------------------------------------
# Build the installer (used for both test and release builds).
# ---------------------------------------------------------------
- name: Build the installer
run: |
cmd /C "C:\Program Files (x86)\NSIS\Bin\makensis.exe" ".\installer\installer.nsi"
- uses: actions/upload-artifact@v4

# ---------------------------------------------------------------
# Upload the unsigned installer – the release job will sign it.
# ---------------------------------------------------------------
- name: Upload unsigned installer
id: upload-unsigned-installer
uses: actions/upload-artifact@v7
with:
name: Installer
name: unsigned-installer
path: installer/*.exe
archive: false # Do not zip the NSIS installer.

# ---------------------------------------------------------------------
# Release job – runs _only_ for tag pushes and requires manual approval.
# ---------------------------------------------------------------------
release:
needs: build
if: startsWith(github.ref, 'refs/tags/')
runs-on: windows-2025
environment: production # <-- manual approval point
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v3
with:
submodules: true

# Download the signed binaries produced by the build job.
- name: Download signed binaries
uses: actions/download-artifact@v4
with:
name: signed-binaries
path: signed-binaries

# ---------------------------------------------------------------
# ----- Release signing for binaries (tag only) -----
# Requires the production environment approval.
# ---------------------------------------------------------------
- name: Sign binaries (release)
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '44e7ac31-01b7-47df-8a58-44125a7d21b0'
project-slug: 'PIME'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'binaries-zip'
github-artifact-id: '${{ steps.upload-unsigned-binaries.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'signed-binaries'

# Replace binaries with the newly signed versions.
- name: Replace binaries with signed versions
run: |
copy signed-binaries\build\PIMELauncher\PIMELauncher.exe build\PIMELauncher\PIMELauncher.exe
copy signed-binaries\build\PIMETextService\Release\PIMETextService.dll build\PIMETextService\Release\PIMETextService.dll
copy signed-binaries\build64\PIMETextService\Release\PIMETextService.dll build64\PIMETextService\Release\PIMETextService.dll
copy signed-binaries\build_arm64\PIMETextService\Release\PIMETextService.dll build_arm64\PIMETextService\Release\PIMETextService.dll

# ---------------------------------------------------------------
# Download the unsigned installer uploaded by the build job.
# ---------------------------------------------------------------
- name: Download unsigned installer
uses: actions/download-artifact@v4
with:
name: unsigned-installer
path: unsigned-installer

# ----- Release installer signing (tag only) -----
- name: Sign installer
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '44e7ac31-01b7-47df-8a58-44125a7d21b0'
project-slug: 'PIME'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'initial' # single .exe file
github-artifact-id: '${{ steps.upload-unsigned-installer.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'signed-installer'
skip-decompress: true # installer exe is not a zip file.

# ----- Create GitHub Release (tag only) -----
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: signed-installer/**/*.exe
generate_release_notes: true
9 changes: 8 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pull_requests:
do_not_increment_build_number: true

version: "{branch} build {build}"
image: Visual Studio 2022
image: Visual Studio 2026

init:
- git --version
Expand All @@ -16,6 +16,13 @@ install:
- git submodule init
- git submodule update

# The appveyor image contains cmake 4.1 only, which doesn't support VS 2016.
# Download cmake 4.3.0 and add it to the PATH.
- appveyor DownloadFile https://cmake.org/files/v4.3/cmake-4.3.0-windows-x86_64.zip -FileName cmake43.zip
- 7z x cmake43.zip -oC:\cmake43
- set "PATH=C:\cmake43\cmake-4.3.0-windows-x86_64\bin;%PATH%"
- cmake --version # should print 4.3.0

build_script:
- .\build.bat

Expand Down
6 changes: 3 additions & 3 deletions build.bat
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
cmake . -Bbuild -G "Visual Studio 17 2022" -A Win32 -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake . -Bbuild -G "Visual Studio 18 2026" -A Win32 -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake --build build --config Release

cmake . -Bbuild64 -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake . -Bbuild64 -G "Visual Studio 18 2026" -A x64 -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake --build build64 --config Release --target PIMETextService

cmake . -Bbuild_arm64 -G "Visual Studio 17 2022" -A ARM64 -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake . -Bbuild_arm64 -G "Visual Studio 18 2026" -A ARM64 -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake --build build_arm64 --config Release --target PIMETextService


Expand Down
Loading