Files
msime-windows/.github/workflows/release.yml
T
Evan 0761b410e3 Merge pull request #122 from metasequoiaime/fix/installer-language-file
fix(ci): supply the Inno Setup language file, and move release shell into scripts/ci
2026-09-05 17:21:36 +09:00

390 lines
15 KiB
YAML

name: Release
on:
push:
branches:
- main
workflow_dispatch:
inputs:
tag:
description: Existing draft release tag to build and publish, for example v0.0.10
required: true
type: string
dictionary_tag:
description: MSIME-Dict release to take the dictionaries from, or "latest"
required: false
type: string
default: latest
permissions:
contents: read
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
# The installer scripts address sibling checkouts by their historical directory names.
# Staging under these names is what lets msime-installer run unmodified in CI.
STAGING_ROOT: src
# Where the packaging job finds this repository's scripts, since it checks out several.
TSF_ROOT: src/MetasequoiaImeTsf
jobs:
prepare:
name: Prepare release metadata
runs-on: ubuntu-24.04
permissions:
contents: write
pull-requests: write
outputs:
should_publish: ${{ github.event_name == 'workflow_dispatch' || steps.release.outputs.release_created == 'true' }}
tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || steps.release.outputs.tag_name }}
version: ${{ github.event_name == 'workflow_dispatch' && steps.requested_release.outputs.version || steps.release.outputs.version }}
target_sha: ${{ github.event_name == 'workflow_dispatch' && steps.requested_release.outputs.target_sha || steps.release.outputs.sha }}
dictionary_tag: ${{ github.event_name == 'workflow_dispatch' && inputs.dictionary_tag || 'latest' }}
steps:
- name: Check out release automation
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Prepare release
if: ${{ github.event_name == 'push' }}
id: release
uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Merge the release pull request
if: ${{ github.event_name == 'push' && steps.release.outputs.prs_created == 'true' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
RELEASE_PR: ${{ steps.release.outputs.pr }}
run: bash scripts/ci/merge-release-pr.sh
- name: Validate requested draft release
if: ${{ github.event_name == 'workflow_dispatch' }}
id: requested_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
TAG_NAME: ${{ inputs.tag }}
run: bash scripts/ci/validate-draft-release.sh
tsf:
name: Build TSF ${{ matrix.name }}
needs: prepare
if: ${{ needs.prepare.outputs.should_publish == 'true' }}
runs-on: windows-2025
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- name: x64
architecture: x64
triplet: x64-windows-static
build_dir: build64-release
- name: Win32
architecture: Win32
triplet: x86-windows-static
build_dir: build32-release
steps:
- name: Check out release commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.prepare.outputs.target_sha }}
submodules: recursive
persist-credentials: false
- name: Stamp the version resource
shell: pwsh
run: |
python scripts/apply_version.py
python scripts/apply_version.py --check
- name: Install dependencies
shell: pwsh
run: vcpkg install --triplet ${{ matrix.triplet }}
# CMakePresets.json points at a developer machine's vcpkg, so the presets cannot be used
# here. This mirrors what .github/workflows/ci.yml already does, into the build directory
# layout that msime-installer's Prepare-PackageFiles.ps1 expects.
- name: Configure
shell: pwsh
run: >
cmake -S . -B ${{ matrix.build_dir }} -A ${{ matrix.architecture }}
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
-DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }}
- name: Build
shell: pwsh
run: cmake --build ${{ matrix.build_dir }} --config Release --parallel
- name: Check the DLL the installer expects
shell: pwsh
run: ./scripts/ci/check-tsf-dll.ps1 -BuildDir '${{ matrix.build_dir }}'
- name: Upload the DLL
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: tsf-${{ matrix.name }}
path: ${{ matrix.build_dir }}/Release/MetasequoiaImeTsf.dll
if-no-files-found: error
server:
name: Build Server
needs: prepare
if: ${{ needs.prepare.outputs.should_publish == 'true' }}
runs-on: windows-2025
timeout-minutes: 90
steps:
- name: Check out MSIME-Server
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: metasequoiaime/MSIME-Server
submodules: recursive
persist-credentials: false
# After the checkout above, which cleans the workspace root: a checkout into a subdirectory
# does not touch its parent, so the order matters.
- name: Check out release automation
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
path: automation
sparse-checkout: scripts/ci
persist-credentials: false
- name: Install Boost
shell: pwsh
run: ./automation/scripts/ci/install-boost.ps1
# The binary directory has to be named build: MSIME-Server's CMakeLists.txt hardcodes
# ${CMAKE_SOURCE_DIR}/build/vcpkg_installed for the WebView2 loader and its include paths,
# so any other name fails to link MetasequoiaImeSettings. The packaging job downloads this
# artifact into build-release/bin/Release, which is where Prepare-PackageFiles.ps1 reads it
# from, so the name used here does not matter.
- name: Configure
shell: pwsh
run: >
cmake -S . -B build -A x64
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
-DVCPKG_TARGET_TRIPLET=x64-windows
- name: Build
shell: pwsh
run: cmake --build build --config Release --parallel
- name: Check the binaries the installer requires
shell: pwsh
run: ./automation/scripts/ci/check-server-binaries.ps1
- name: Upload the Server build
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: server
path: build/bin/Release
if-no-files-found: error
ui:
name: Build settings page
needs: prepare
if: ${{ needs.prepare.outputs.should_publish == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Check out MetasequoiaImeUiHtml
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: metasequoiaime/MetasequoiaImeUiHtml
persist-credentials: false
- name: Set up pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with:
version: 10
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: pnpm
cache-dependency-path: webview2/settings/ime-settings/pnpm-lock.yaml
- name: Install and build the settings page
working-directory: webview2/settings/ime-settings
run: |
pnpm install --frozen-lockfile
pnpm build
- name: Upload the web assets
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: webview2
path: |
webview2/candwnd
webview2/ftb
webview2/menu
webview2/settings/ime-settings/dist
if-no-files-found: error
package:
name: Package and publish installer
needs: [prepare, tsf, server, ui]
runs-on: windows-2025
timeout-minutes: 60
permissions:
contents: write
env:
# jrsoftware/issrc pinned by commit, with the checksum of the file at that commit.
ISL_URL: https://raw.githubusercontent.com/jrsoftware/issrc/1ae7bf81dc0d2013235dfe4bb0b6f4e4a0b6b25c/Files/Languages/ChineseSimplified.isl
ISL_SHA256: e0b0b350e2245f3c5e65586dfe43d574f6e7f06f2261149aba284954b3fc9a8d
steps:
- name: Check out MSIME-Windows at the release commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.prepare.outputs.target_sha }}
path: ${{ env.TSF_ROOT }}
persist-credentials: false
- name: Verify the release commit is on main
shell: bash
working-directory: ${{ env.TSF_ROOT }}
run: bash scripts/ci/verify-commit-on-main.sh
- name: Check out the installer
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: metasequoiaime/msime-installer
path: ${{ env.STAGING_ROOT }}/msime-installer
persist-credentials: false
- name: Check out MSIME-Server sources
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: metasequoiaime/MSIME-Server
path: ${{ env.STAGING_ROOT }}/MetasequoiaImeServer
persist-credentials: false
- name: Check out MSIME-HelpCode
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: metasequoiaime/MSIME-HelpCode
path: ${{ env.STAGING_ROOT }}/MetasequoiaImeHelpCode
persist-credentials: false
- name: Download the TSF DLLs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: tsf-x64
path: ${{ env.TSF_ROOT }}/build64-release/Release
- name: Download the 32-bit TSF DLL
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: tsf-Win32
path: ${{ env.TSF_ROOT }}/build32-release/Release
- name: Download the Server build
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: server
path: ${{ env.STAGING_ROOT }}/MetasequoiaImeServer/build-release/bin/Release
- name: Download the web assets
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: webview2
path: ${{ env.STAGING_ROOT }}/MetasequoiaImeUiHtml/webview2
- name: Download the dictionaries
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DICTIONARY_TAG: ${{ needs.prepare.outputs.dictionary_tag }}
run: bash ${{ env.TSF_ROOT }}/scripts/ci/download-dictionaries.sh
- name: Decide the signing mode
id: signing
shell: pwsh
env:
CERTIFICATE_BASE64: ${{ secrets.WINDOWS_SIGNING_CERTIFICATE_BASE64 }}
CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}
run: ./${{ env.TSF_ROOT }}/scripts/ci/detect-release-signing.ps1
- name: Collect the installer payload
shell: pwsh
working-directory: ${{ env.STAGING_ROOT }}/msime-installer
env:
TARGET_VERSION: ${{ needs.prepare.outputs.version }}
run: pwsh -File ./Prepare-PackageFiles.ps1 -TargetVersion $env:TARGET_VERSION -RepoRoot (Resolve-Path '..').Path
- name: Sign the packaged binaries
if: ${{ steps.signing.outputs.signing_enabled == 'true' }}
shell: pwsh
working-directory: ${{ env.STAGING_ROOT }}/msime-installer
env:
CERTIFICATE_BASE64: ${{ secrets.WINDOWS_SIGNING_CERTIFICATE_BASE64 }}
CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}
TIMESTAMP_URL: ${{ vars.WINDOWS_SIGNING_TIMESTAMP_URL || 'http://timestamp.digicert.com' }}
run: ../../${{ env.TSF_ROOT }}/scripts/ci/sign-binaries.ps1 -Path 'server_exe', 'tsf_dll' -Recurse
- name: Install the Chinese language file for Inno Setup
shell: pwsh
run: ./${{ env.TSF_ROOT }}/scripts/ci/install-inno-language.ps1
- name: Compile the installer
shell: pwsh
working-directory: ${{ env.STAGING_ROOT }}/msime-installer
run: pwsh -File ./Compile-Installer.ps1
- name: Sign the installer
if: ${{ steps.signing.outputs.signing_enabled == 'true' }}
shell: pwsh
working-directory: ${{ env.STAGING_ROOT }}/msime-installer
env:
CERTIFICATE_BASE64: ${{ secrets.WINDOWS_SIGNING_CERTIFICATE_BASE64 }}
CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}
TIMESTAMP_URL: ${{ vars.WINDOWS_SIGNING_TIMESTAMP_URL || 'http://timestamp.digicert.com' }}
TARGET_VERSION: ${{ needs.prepare.outputs.version }}
run: ../../${{ env.TSF_ROOT }}/scripts/ci/sign-binaries.ps1 -Path "Output/MetasequoiaIME_Setup_v$env:TARGET_VERSION.exe"
- name: Name the asset and record its checksum
id: asset
shell: pwsh
working-directory: ${{ env.STAGING_ROOT }}/msime-installer
env:
TARGET_VERSION: ${{ needs.prepare.outputs.version }}
ASSET_SUFFIX: ${{ steps.signing.outputs.asset_suffix }}
run: ../../${{ env.TSF_ROOT }}/scripts/ci/name-installer-asset.ps1
- name: Upload the installer as a workflow artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: installer
path: ${{ steps.asset.outputs.asset_path }}
if-no-files-found: error
- name: Revalidate the draft release target
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
TAG_NAME: ${{ needs.prepare.outputs.tag_name }}
TARGET_SHA: ${{ needs.prepare.outputs.target_sha }}
run: bash ${{ env.TSF_ROOT }}/scripts/ci/revalidate-draft-release.sh
- name: Upload and publish the release
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
TAG_NAME: ${{ needs.prepare.outputs.tag_name }}
ASSET_PATH: ${{ steps.asset.outputs.asset_path }}
ASSET_NAME: ${{ steps.asset.outputs.asset_name }}
ASSET_SHA256: ${{ steps.asset.outputs.asset_sha256 }}
SIGNING_ENABLED: ${{ steps.signing.outputs.signing_enabled }}
run: bash ${{ env.TSF_ROOT }}/scripts/ci/publish-release.sh