diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index bd0aebf1..c7ee561f 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -47,7 +47,11 @@ jobs: - name: Temporarily disable panic abort for building run: | - sed -i 's/panic = "abort"/# panic = "abort"/' .cargo/config.toml + if [ -f .cargo/config.toml ]; then + sed -i 's/panic = "abort"/# panic = "abort"/' .cargo/config.toml || true + else + echo ".cargo/config.toml not found; skipping panic profile tweak" + fi - name: Build binaries run: | @@ -172,7 +176,12 @@ jobs: EOF - name: Restore panic abort setting - run: sed -i 's/# panic = "abort"/panic = "abort"/' .cargo/config.toml + run: | + if [ -f .cargo/config.toml ]; then + sed -i 's/# panic = "abort"/panic = "abort"/' .cargo/config.toml || true + else + echo ".cargo/config.toml not found; nothing to restore" + fi - name: Create GitHub Release uses: softprops/action-gh-release@v2 diff --git a/.github/workflows/publish-tauri.yml b/.github/workflows/publish-tauri.yml index 75f96643..920718a0 100644 --- a/.github/workflows/publish-tauri.yml +++ b/.github/workflows/publish-tauri.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v5 - name: Install 1Password CLI - uses: 1password/install-cli-action@v1.1.0 + uses: 1password/install-cli-action@v1 - name: Setup Node.js uses: actions/setup-node@v5 @@ -38,32 +38,67 @@ jobs: - name: Install Rust stable uses: dtolnay/rust-toolchain@stable + - name: Load 1Password secrets + uses: 1password/load-secrets-action@v2 + with: + export-env: true + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + # These references must exist in the 1Password vault accessible to the service account + # TAURI_PRIVATE_KEY is required for signing the updater + # TAURI_PUBLIC_KEY is injected into the Tauri configuration (via op inject step below) + secrets: | + TAURI_PRIVATE_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PRIVATE_KEY + TAURI_PUBLIC_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PUBLIC_KEY + - name: Install dependencies (Ubuntu) if: startsWith(matrix.platform, 'ubuntu-') run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev ${{ matrix.webkit-package }} libjavascriptcoregtk-4.0-dev libsoup2.4-dev libayatana-appindicator3-dev librsvg2-dev pkg-config + - name: WebKitGTK 4.1 compatibility shim (Ubuntu) + if: startsWith(matrix.platform, 'ubuntu-') + run: | + set -e + PC_DIR=/usr/lib/x86_64-linux-gnu/pkgconfig + LIB_DIR=/usr/lib/x86_64-linux-gnu + if [ -f "$PC_DIR/webkit2gtk-4.1.pc" ] && [ ! -f "$PC_DIR/webkit2gtk-4.0.pc" ]; then + echo "Creating pkg-config shim for webkit2gtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/webkit2gtk-4.1.pc" "$PC_DIR/webkit2gtk-4.0.pc" + fi + if [ -f "$PC_DIR/javascriptcoregtk-4.1.pc" ] && [ ! -f "$PC_DIR/javascriptcoregtk-4.0.pc" ]; then + echo "Creating pkg-config shim for javascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/javascriptcoregtk-4.1.pc" "$PC_DIR/javascriptcoregtk-4.0.pc" + fi + if [ -f "$LIB_DIR/libwebkit2gtk-4.1.so" ] && [ ! -f "$LIB_DIR/libwebkit2gtk-4.0.so" ]; then + echo "Creating library shim for libwebkit2gtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libwebkit2gtk-4.1.so" "$LIB_DIR/libwebkit2gtk-4.0.so" + fi + if [ -f "$LIB_DIR/libjavascriptcoregtk-4.1.so" ] && [ ! -f "$LIB_DIR/libjavascriptcoregtk-4.0.so" ]; then + echo "Creating library shim for libjavascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libjavascriptcoregtk-4.1.so" "$LIB_DIR/libjavascriptcoregtk-4.0.so" + fi + - name: Install frontend dependencies run: yarn install working-directory: ${{env.working-directory}} - - name: Inject secrets and build with Tauri + - name: Generate Tauri config from template env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} working-directory: ${{env.working-directory}} run: | - # Inject secrets into Tauri configuration op inject --force -i src-tauri/tauri.conf.json.template -o src-tauri/tauri.conf.json chmod 600 src-tauri/tauri.conf.json - # Create environment file for signing - cat > .env.ci << 'EOF' - TAURI_PRIVATE_KEY="op://TerraphimPlatform/tauri.update.signing/TAURI_PRIVATE_KEY" - EOF - - # Build with injected signing keys - op run --env-file=.env.ci -- yarn run tauri build + - name: Build with Tauri (signed) + working-directory: ${{env.working-directory}} + env: + # Provided by 1Password load-secrets action + TAURI_PRIVATE_KEY: ${{ env.TAURI_PRIVATE_KEY }} + run: | + yarn run tauri build - name: Generate updater manifest if: matrix.platform == 'ubuntu-22.04' diff --git a/.github/workflows/release-comprehensive.yml b/.github/workflows/release-comprehensive.yml index 13446903..2aea464b 100644 --- a/.github/workflows/release-comprehensive.yml +++ b/.github/workflows/release-comprehensive.yml @@ -148,6 +148,19 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 + - name: Install 1Password CLI + uses: 1password/install-cli-action@v1 + + - name: Load 1Password secrets + uses: 1password/load-secrets-action@v2 + with: + export-env: true + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + secrets: | + TAURI_PRIVATE_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PRIVATE_KEY + TAURI_PUBLIC_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PUBLIC_KEY + - name: Setup Node.js uses: actions/setup-node@v5 with: @@ -170,15 +183,47 @@ jobs: sudo apt-get install -y libgtk-3-dev ${{ matrix.webkit-package }} \ libjavascriptcoregtk-4.0-dev libsoup2.4-dev libayatana-appindicator3-dev librsvg2-dev pkg-config + - name: WebKitGTK 4.1 compatibility shim (Ubuntu) + if: startsWith(matrix.platform, 'ubuntu-') + run: | + set -e + PC_DIR=/usr/lib/x86_64-linux-gnu/pkgconfig + LIB_DIR=/usr/lib/x86_64-linux-gnu + if [ -f "$PC_DIR/webkit2gtk-4.1.pc" ] && [ ! -f "$PC_DIR/webkit2gtk-4.0.pc" ]; then + echo "Creating pkg-config shim for webkit2gtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/webkit2gtk-4.1.pc" "$PC_DIR/webkit2gtk-4.0.pc" + fi + if [ -f "$PC_DIR/javascriptcoregtk-4.1.pc" ] && [ ! -f "$PC_DIR/javascriptcoregtk-4.0.pc" ]; then + echo "Creating pkg-config shim for javascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/javascriptcoregtk-4.1.pc" "$PC_DIR/javascriptcoregtk-4.0.pc" + fi + if [ -f "$LIB_DIR/libwebkit2gtk-4.1.so" ] && [ ! -f "$LIB_DIR/libwebkit2gtk-4.0.so" ]; then + echo "Creating library shim for libwebkit2gtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libwebkit2gtk-4.1.so" "$LIB_DIR/libwebkit2gtk-4.0.so" + fi + if [ -f "$LIB_DIR/libjavascriptcoregtk-4.1.so" ] && [ ! -f "$LIB_DIR/libjavascriptcoregtk-4.0.so" ]; then + echo "Creating library shim for libjavascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libjavascriptcoregtk-4.1.so" "$LIB_DIR/libjavascriptcoregtk-4.0.so" + fi + - name: Install frontend dependencies working-directory: ./desktop run: yarn install --frozen-lockfile - - name: Build Tauri app + - name: Generate Tauri config from template + working-directory: ./desktop + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + run: | + op inject --force -i src-tauri/tauri.conf.json.template -o src-tauri/tauri.conf.json + chmod 600 src-tauri/tauri.conf.json + + - name: Build Tauri app (signed) working-directory: ./desktop - run: yarn tauri build env: + TAURI_PRIVATE_KEY: ${{ env.TAURI_PRIVATE_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: yarn tauri build - name: Upload desktop artifacts (macOS) if: matrix.platform == 'macos-latest' @@ -236,7 +281,7 @@ jobs: mkdir -p release-assets # Copy binary artifacts - find binaries-* -type f -executable -o -name "*.exe" | while read file; do + find binaries-* \( -type f -executable -o -type f -name "*.exe" \) | while read file; do cp "$file" release-assets/ done diff --git a/.github/workflows/tauri-build.yml b/.github/workflows/tauri-build.yml index 177cb36d..b5cfb30d 100644 --- a/.github/workflows/tauri-build.yml +++ b/.github/workflows/tauri-build.yml @@ -31,6 +31,19 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 + - name: Install 1Password CLI + uses: 1password/install-cli-action@v1 + + - name: Load 1Password secrets + uses: 1password/load-secrets-action@v2 + with: + export-env: true + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + secrets: | + TAURI_PRIVATE_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PRIVATE_KEY + TAURI_PUBLIC_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PUBLIC_KEY + - name: Setup Node.js uses: actions/setup-node@v5 with: @@ -67,19 +80,51 @@ jobs: libjavascriptcoregtk-4.0-dev \ pkg-config + - name: WebKitGTK 4.1 compatibility shim (Ubuntu) + if: matrix.platform == 'ubuntu-20.04' || matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-24.04' + run: | + set -e + PC_DIR=/usr/lib/x86_64-linux-gnu/pkgconfig + LIB_DIR=/usr/lib/x86_64-linux-gnu + if [ -f "$PC_DIR/webkit2gtk-4.1.pc" ] && [ ! -f "$PC_DIR/webkit2gtk-4.0.pc" ]; then + echo "Creating pkg-config shim for webkit2gtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/webkit2gtk-4.1.pc" "$PC_DIR/webkit2gtk-4.0.pc" + fi + if [ -f "$PC_DIR/javascriptcoregtk-4.1.pc" ] && [ ! -f "$PC_DIR/javascriptcoregtk-4.0.pc" ]; then + echo "Creating pkg-config shim for javascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/javascriptcoregtk-4.1.pc" "$PC_DIR/javascriptcoregtk-4.0.pc" + fi + if [ -f "$LIB_DIR/libwebkit2gtk-4.1.so" ] && [ ! -f "$LIB_DIR/libwebkit2gtk-4.0.so" ]; then + echo "Creating library shim for libwebkit2gtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libwebkit2gtk-4.1.so" "$LIB_DIR/libwebkit2gtk-4.0.so" + fi + if [ -f "$LIB_DIR/libjavascriptcoregtk-4.1.so" ] && [ ! -f "$LIB_DIR/libjavascriptcoregtk-4.0.so" ]; then + echo "Creating library shim for libjavascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libjavascriptcoregtk-4.1.so" "$LIB_DIR/libjavascriptcoregtk-4.0.so" + fi + - name: Install frontend dependencies working-directory: ${{ env.WORKING_DIRECTORY }} run: yarn install --frozen-lockfile + - name: Generate Tauri config from template + working-directory: ${{ env.WORKING_DIRECTORY }} + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + run: | + op inject --force -i src-tauri/tauri.conf.json.template -o src-tauri/tauri.conf.json + chmod 600 src-tauri/tauri.conf.json + - name: Build frontend working-directory: ${{ env.WORKING_DIRECTORY }} run: yarn run build - - name: Build Tauri app + - name: Build Tauri app (signed) working-directory: ${{ env.WORKING_DIRECTORY }} - run: yarn tauri build env: + TAURI_PRIVATE_KEY: ${{ env.TAURI_PRIVATE_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: yarn tauri build - name: Collect artifact paths id: artifacts diff --git a/.github/workflows/test-on-pr-desktop.yml b/.github/workflows/test-on-pr-desktop.yml index c3c5ea55..48a59858 100644 --- a/.github/workflows/test-on-pr-desktop.yml +++ b/.github/workflows/test-on-pr-desktop.yml @@ -29,10 +29,10 @@ jobs: steps: - uses: actions/checkout@v5 - - name: Setup Node.js + - name: Setup Node.js (LTS) uses: actions/setup-node@v5 with: - node-version: latest + node-version: 20 - name: Install Rust stable uses: actions-rs/toolchain@v1 @@ -45,12 +45,55 @@ jobs: if: startsWith(matrix.platform, 'ubuntu-') run: | sudo apt-get update - sudo apt-get install -y libgtk-3-dev ${{ matrix.webkit-package }} libjavascriptcoregtk-4.0-dev libsoup2.4-dev libayatana-appindicator3-dev librsvg2-dev pkg-config + # Try WebKitGTK 4.0 first; on Ubuntu 24.04 this may fail, so fall back to 4.1 + sudo apt-get install -y libgtk-3-dev ${{ matrix.webkit-package }} libjavascriptcoregtk-4.0-dev libsoup2.4-dev libayatana-appindicator3-dev librsvg2-dev pkg-config \ + || sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev libsoup2.4-dev libayatana-appindicator3-dev librsvg2-dev pkg-config + + - name: WebKitGTK 4.1 compatibility shim (Ubuntu) + if: startsWith(matrix.platform, 'ubuntu-') + run: | + set -e + PC_DIR=/usr/lib/x86_64-linux-gnu/pkgconfig + LIB_DIR=/usr/lib/x86_64-linux-gnu + # Only create shims if 4.1 exists and 4.0 is missing + if [ -f "$PC_DIR/webkit2gtk-4.1.pc" ] && [ ! -f "$PC_DIR/webkit2gtk-4.0.pc" ]; then + echo "Creating pkg-config shim for webkit2gtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/webkit2gtk-4.1.pc" "$PC_DIR/webkit2gtk-4.0.pc" + fi + if [ -f "$PC_DIR/javascriptcoregtk-4.1.pc" ] && [ ! -f "$PC_DIR/javascriptcoregtk-4.0.pc" ]; then + echo "Creating pkg-config shim for javascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$PC_DIR/javascriptcoregtk-4.1.pc" "$PC_DIR/javascriptcoregtk-4.0.pc" + fi + if [ -f "$LIB_DIR/libwebkit2gtk-4.1.so" ] && [ ! -f "$LIB_DIR/libwebkit2gtk-4.0.so" ]; then + echo "Creating library shim for libwebkit2gtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libwebkit2gtk-4.1.so" "$LIB_DIR/libwebkit2gtk-4.0.so" + fi + if [ -f "$LIB_DIR/libjavascriptcoregtk-4.1.so" ] && [ ! -f "$LIB_DIR/libjavascriptcoregtk-4.0.so" ]; then + echo "Creating library shim for libjavascriptcoregtk 4.0 -> 4.1" + sudo ln -sf "$LIB_DIR/libjavascriptcoregtk-4.1.so" "$LIB_DIR/libjavascriptcoregtk-4.0.so" + fi - name: Install and Build Application - run: yarn install && yarn build + run: yarn install --frozen-lockfile && yarn build working-directory: ${{ env.WORKING_DIRECTORY }} + - name: Prepare Tauri config (no secrets on PRs) + working-directory: ${{ env.WORKING_DIRECTORY }} + run: | + if [ -f src-tauri/tauri.conf.json ]; then + echo "tauri.conf.json already present" + exit 0 + fi + if [ -f src-tauri/tauri.conf.json.template ]; then + cp src-tauri/tauri.conf.json.template src-tauri/tauri.conf.json + # Replace any op:// references with a dummy placeholder so build does not fail + sed -i.bak 's|"op://[^"]*"|"DEV_NO_KEY"|g' src-tauri/tauri.conf.json || true + rm -f src-tauri/tauri.conf.json.bak || true + echo "Prepared src-tauri/tauri.conf.json from template" + else + echo "No tauri.conf.json or template found" + fi + - uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/GITHUB_ACTIONS_1PASSWORD.md b/docs/GITHUB_ACTIONS_1PASSWORD.md new file mode 100644 index 00000000..fbb9a971 --- /dev/null +++ b/docs/GITHUB_ACTIONS_1PASSWORD.md @@ -0,0 +1,65 @@ +# GitHub Actions + 1Password Integration (Aligned with PR #290) + +This guide documents how our CI uses 1Password to fetch secrets directly from the vault at build time, without storing long‑lived secrets in GitHub. The only GitHub secret required is `OP_SERVICE_ACCOUNT_TOKEN`. + +## Prerequisites + +- Create a 1Password Service Account scoped to the vault containing release keys (e.g., `TerraphimPlatform`). +- Add the service account token to the repository: `Settings → Secrets and variables → Actions → New repository secret` named `OP_SERVICE_ACCOUNT_TOKEN`. +- Ensure these items exist in the vault and are readable by the service account: + - `tauri.update.signing / TAURI_PRIVATE_KEY` (concealed) + - `tauri.update.signing / TAURI_PUBLIC_KEY` (text) + +## Recommended Pattern (load-secrets-action@v2) + +```yaml +- name: Install 1Password CLI + uses: 1password/install-cli-action@v1 + +- name: Load 1Password secrets + uses: 1password/load-secrets-action@v2 + with: + export-env: true + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + secrets: | + TAURI_PRIVATE_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PRIVATE_KEY + TAURI_PUBLIC_KEY=op://TerraphimPlatform/tauri.update.signing/TAURI_PUBLIC_KEY + +# If your config template includes op:// references, inject them using the CLI +- name: Generate Tauri config from template + working-directory: ./desktop + env: + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + run: | + op inject --force -i src-tauri/tauri.conf.json.template -o src-tauri/tauri.conf.json + +# Build with signing key provided from 1Password via environment +- name: Build Tauri app (signed) + working-directory: ./desktop + env: + TAURI_PRIVATE_KEY: ${{ env.TAURI_PRIVATE_KEY }} + run: yarn tauri build +``` + +Notes: +- Use `load-secrets-action@v2` to export environment variables from 1Password directly. +- Use `op inject` only when you must render templates containing `op://` references (e.g., public keys in `tauri.conf.json`). + +## Where This Is Used + +- `.github/workflows/publish-tauri.yml` — publishes signed Tauri builds and `latest.json` (auto‑update). +- `.github/workflows/release-comprehensive.yml` — includes desktop build matrix; now loads secrets for signing. + +## Troubleshooting + +- Missing or invalid `OP_SERVICE_ACCOUNT_TOKEN` → 1Password steps fail. Verify the secret exists and the service account has read access to the vault. +- `op inject` cannot resolve references → verify vault/item/field names match the `op://Vault/Item/Field` scheme. +- Unsigned builds → ensure `TAURI_PRIVATE_KEY` is present in the loaded secrets; Tauri will skip signing if not provided. + +## Security + +- Only the service account token is stored in GitHub secrets; actual signing keys live in 1Password. +- Restrict the service account to read‑only access on the minimal vault scope. + +This reflects the approach introduced in PR #290 and is now the canonical method for CI secret handling.