Consolidate separate platform CI build workflows and improve !build comment commands
This commit is contained in:
parent
efd142f030
commit
df8001fca8
|
|
@ -1,78 +0,0 @@
|
|||
name: "Build Linux Bundle"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
push_to_cache:
|
||||
description: "Push to Nix Cache"
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: ❄ Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
|
||||
- name: 🗑 Free disk space
|
||||
run: sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache
|
||||
|
||||
- name: 📦 Build Nix package
|
||||
run: nix build --no-link --print-out-paths
|
||||
|
||||
- name: 📤 Push to Nix cache
|
||||
if: github.ref == 'refs/heads/master' || inputs.push_to_cache == true
|
||||
env:
|
||||
NIX_CACHE_AUTH_TOKEN: ${{ secrets.NIX_CACHE_AUTH_TOKEN }}
|
||||
run: |
|
||||
nix run nixpkgs#cachix -- authtoken $NIX_CACHE_AUTH_TOKEN
|
||||
nix build --no-link --print-out-paths | nix run nixpkgs#cachix -- push graphite
|
||||
|
||||
- name: 🏗 Build Linux bundle
|
||||
run: nix build .#graphite-bundle.tar.xz && cp ./result ./graphite-linux-bundle.tar.xz
|
||||
|
||||
- name: 📦 Upload Linux bundle
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-linux-bundle
|
||||
path: graphite-linux-bundle.tar.xz
|
||||
compression-level: 0
|
||||
|
||||
- name: 🔧 Install Flatpak tooling
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y flatpak flatpak-builder
|
||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
- name: 🏗 Build Flatpak
|
||||
run: |
|
||||
nix build .#graphite-flatpak-manifest
|
||||
|
||||
rm -rf .flatpak
|
||||
mkdir -p .flatpak
|
||||
|
||||
cp ./result .flatpak/manifest.json
|
||||
|
||||
cd .flatpak
|
||||
mkdir -p repo
|
||||
|
||||
flatpak-builder --user --force-clean --install-deps-from=flathub --repo=repo build ./manifest.json
|
||||
|
||||
flatpak build-bundle repo Graphite.flatpak art.graphite.Graphite --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
- name: 📦 Upload Flatpak package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-flatpak
|
||||
path: .flatpak/Graphite.flatpak
|
||||
compression-level: 0
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
name: "Build Mac Bundle"
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
WASM_BINDGEN_CLI_VERSION: "0.2.100"
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: 💾 Set up Cargo cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: npm
|
||||
cache-dependency-path: |
|
||||
package-lock.json
|
||||
frontend/package-lock.json
|
||||
|
||||
- name: 🚧 Install native dependencies
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
BINSTALL_DISABLE_TELEMETRY: "true"
|
||||
run: |
|
||||
brew update
|
||||
brew install \
|
||||
pkg-config \
|
||||
openssl@3 \
|
||||
binaryen \
|
||||
llvm \
|
||||
cargo-binstall
|
||||
|
||||
echo "OPENSSL_DIR=$(brew --prefix openssl@3)" >> $GITHUB_ENV
|
||||
echo "PKG_CONFIG_PATH=$(brew --prefix openssl@3)/lib/pkgconfig" >> $GITHUB_ENV
|
||||
echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH
|
||||
|
||||
cargo binstall --no-confirm --force wasm-pack
|
||||
cargo binstall --no-confirm --force cargo-about
|
||||
cargo binstall --no-confirm --force "wasm-bindgen-cli@${WASM_BINDGEN_CLI_VERSION}"
|
||||
|
||||
- name: 🏗 Build Mac bundle
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
run: cargo run build desktop
|
||||
|
||||
- name: 📁 Stage artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
rm -rf target/artifacts
|
||||
mkdir -p target/artifacts
|
||||
cp -R target/release/Graphite.app target/artifacts/Graphite.app
|
||||
|
||||
- name: 📦 Upload Mac bundle
|
||||
if: github.ref != 'refs/heads/master'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-mac-bundle
|
||||
path: target/artifacts
|
||||
|
||||
- name: 🔏 Sign and notarize (preparation)
|
||||
if: github.ref == 'refs/heads/master'
|
||||
env:
|
||||
APPLE_CERT_BASE64: ${{ secrets.APPLE_CERT_BASE64 }}
|
||||
APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
|
||||
run: |
|
||||
mkdir -p .sign
|
||||
echo "$APPLE_CERT_BASE64" | base64 --decode > .sign/certificate.p12
|
||||
|
||||
security create-keychain -p "" .sign/main.keychain
|
||||
security default-keychain -s .sign/main.keychain
|
||||
security unlock-keychain -p "" .sign/main.keychain
|
||||
security set-keychain-settings -t 3600 -u .sign/main.keychain
|
||||
|
||||
security import .sign/certificate.p12 -k .sign/main.keychain -P "$APPLE_CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "" .sign/main.keychain
|
||||
|
||||
cat > .sign/entitlements.plist <<'EOF'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
- name: 🔏 Sign and notarize
|
||||
if: github.ref == 'refs/heads/master'
|
||||
env:
|
||||
APPLE_EMAIL: ${{ secrets.APPLE_EMAIL }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_CERT_NAME: ${{ secrets.APPLE_CERT_NAME }}
|
||||
run: |
|
||||
CERTIFICATE="$APPLE_CERT_NAME"
|
||||
ENTITLEMENTS=".sign/entitlements.plist"
|
||||
APP_PATH="target/artifacts/Graphite.app"
|
||||
ZIP_PATH=".sign/Graphite.zip"
|
||||
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Graphite Helper.app"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Graphite Helper (GPU).app"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Graphite Helper (Renderer).app"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libcef_sandbox.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libEGL.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libGLESv2.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libvk_swiftshader.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH" --deep
|
||||
|
||||
codesign --verify --deep --strict --verbose=4 "$APP_PATH"
|
||||
|
||||
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
|
||||
xcrun notarytool submit "$ZIP_PATH" --wait --apple-id "$APPLE_EMAIL" --team-id "$APPLE_TEAM_ID" --password "$APPLE_PASSWORD"
|
||||
rm "$ZIP_PATH"
|
||||
|
||||
xcrun stapler staple -v "$APP_PATH"
|
||||
|
||||
spctl -a -vv "$APP_PATH"
|
||||
|
||||
- name: 📦 Upload signed Mac bundle
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-mac-bundle-signed
|
||||
path: target/artifacts
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
name: "Build Nix Package"
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: ❄ Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
|
||||
- name: 💾 Set up Nix cache
|
||||
uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
|
||||
- name: 📦 Build Nix package dev
|
||||
run: nix build .#graphite-dev --print-build-logs
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
name: "Build Web Bundle"
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="dev.graphite.art" data-api="https://graphite.art/visit/event" src="https://graphite.art/visit/script.hash.js"></script>
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: [self-hosted, target/wasm]
|
||||
permissions:
|
||||
contents: write
|
||||
deployments: write
|
||||
actions: write
|
||||
env:
|
||||
RUSTC_WRAPPER: /usr/bin/sccache
|
||||
CARGO_INCREMENTAL: 0
|
||||
SCCACHE_DIR: /var/lib/github-actions/.cache
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🗑 Clear wasm-bindgen cache
|
||||
run: rm -r ~/.cache/.wasm-pack || true
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: 🚧 Install build dependencies
|
||||
run: |
|
||||
cd frontend
|
||||
npm run setup
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: ✂ Replace template in <head> of index.html
|
||||
run: |
|
||||
sed -i "s|<!-- INDEX_HTML_HEAD_REPLACEMENT -->|$INDEX_HTML_HEAD_REPLACEMENT|" frontend/index.html
|
||||
|
||||
- name: 🌐 Build Graphite web code
|
||||
env:
|
||||
NODE_ENV: production
|
||||
run: mold -run cargo run build web
|
||||
|
||||
- name: 📤 Publish to Cloudflare Pages
|
||||
id: cloudflare
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
run: |
|
||||
MAX_ATTEMPTS=5
|
||||
DELAY=30
|
||||
for ATTEMPT in $(seq 1 $MAX_ATTEMPTS); do
|
||||
echo "Attempt $ATTEMPT of $MAX_ATTEMPTS..."
|
||||
if OUTPUT=$(npx wrangler@3 pages deploy "frontend/dist" --project-name="graphite-dev" --commit-dirty=true 2>&1); then
|
||||
URL=$(echo "$OUTPUT" | grep -oP 'https://[^\s]+\.pages\.dev' | tail -1)
|
||||
echo "url=$URL" >> "$GITHUB_OUTPUT"
|
||||
echo "Published successfully: $URL"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $ATTEMPT failed:"
|
||||
echo "$OUTPUT"
|
||||
if [ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]; then
|
||||
echo "Retrying in ${DELAY}s..."
|
||||
sleep $DELAY
|
||||
DELAY=$((DELAY * 3))
|
||||
fi
|
||||
done
|
||||
echo "All $MAX_ATTEMPTS Cloudflare Pages publish attempts failed."
|
||||
exit 1
|
||||
|
||||
- name: 💬 Comment build link URL to commit hash page on GitHub
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CF_URL: ${{ steps.cloudflare.outputs.url }}
|
||||
run: |
|
||||
if [ -z "$CF_URL" ]; then
|
||||
echo "No Cloudflare URL available, skipping comment."
|
||||
exit 1
|
||||
fi
|
||||
gh api \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
/repos/${{ github.repository }}/commits/$(git rev-parse HEAD)/comments \
|
||||
-f body="| 📦 **Build Complete for** $(git rev-parse HEAD) |
|
||||
|-|
|
||||
| $CF_URL |"
|
||||
|
||||
- name: ✂ Strip analytics script from built output for clean artifact
|
||||
run: |
|
||||
sed -i "s|$INDEX_HTML_HEAD_REPLACEMENT||" frontend/dist/index.html
|
||||
|
||||
- name: 📦 Upload web bundle artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-web-bundle
|
||||
path: frontend/dist
|
||||
|
||||
- name: 📃 Generate code documentation info for website
|
||||
run: |
|
||||
cd tools/editor-message-tree
|
||||
cargo run
|
||||
cd ../..
|
||||
mkdir -p artifacts-generated
|
||||
mv website/generated/hierarchical_message_system_tree.txt artifacts-generated/hierarchical_message_system_tree.txt
|
||||
|
||||
- name: 💿 Obtain cache of auto-generated code docs artifacts, to check if they've changed
|
||||
id: cache-website-code-docs
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: artifacts
|
||||
key: website-code-docs
|
||||
|
||||
- name: 🔍 Check if auto-generated code docs artifacts changed
|
||||
id: website-code-docs-changed
|
||||
run: |
|
||||
if ! diff --brief --recursive artifacts-generated artifacts; then
|
||||
echo "Auto-generated code docs artifacts have changed."
|
||||
rm -rf artifacts
|
||||
mv artifacts-generated artifacts
|
||||
echo "changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Auto-generated code docs artifacts have not changed."
|
||||
rm -rf artifacts
|
||||
rm -rf artifacts-generated
|
||||
fi
|
||||
|
||||
- name: 💾 Save cache of auto-generated code docs artifacts
|
||||
if: steps.website-code-docs-changed.outputs.changed == 'true'
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: artifacts
|
||||
key: ${{ steps.cache-website-code-docs.outputs.cache-primary-key }}
|
||||
|
||||
- name: ♻️ Trigger website rebuild if the auto-generated code docs artifacts have changed
|
||||
if: steps.website-code-docs-changed.outputs.changed == 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
rm -rf artifacts
|
||||
gh workflow run website.yml --ref master
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
name: "Build Windows Bundle"
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
env:
|
||||
WASM_BINDGEN_CLI_VERSION: "0.2.100"
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: 💾 Set up Cargo cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.USERPROFILE }}\.cargo\registry
|
||||
${{ env.USERPROFILE }}\.cargo\git
|
||||
target
|
||||
key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: npm
|
||||
cache-dependency-path: |
|
||||
package-lock.json
|
||||
frontend/package-lock.json
|
||||
|
||||
- name: 📦 Install Cargo-binstall
|
||||
uses: cargo-bins/cargo-binstall@main
|
||||
|
||||
- name: 🚧 Install native dependencies
|
||||
shell: pwsh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
BINSTALL_DISABLE_TELEMETRY: "true"
|
||||
run: |
|
||||
winget install --id LLVM.LLVM -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id Kitware.CMake -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id OpenSSL.OpenSSL -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id WebAssembly.Binaryen -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id GnuWin32.PkgConfig -e --accept-package-agreements --accept-source-agreements
|
||||
|
||||
"OPENSSL_DIR=C:\Program Files\OpenSSL-Win64" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
"PKG_CONFIG_PATH=C:\Program Files\OpenSSL-Win64\lib\pkgconfig" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
cargo binstall --no-confirm --force wasm-pack
|
||||
cargo binstall --no-confirm --force cargo-about
|
||||
cargo binstall --no-confirm --force "wasm-bindgen-cli@$env:WASM_BINDGEN_CLI_VERSION"
|
||||
|
||||
- name: 🏗 Build Windows bundle
|
||||
shell: bash # `cargo-about` refuses to run in powershell
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
run: cargo run build desktop
|
||||
|
||||
- name: 📁 Stage artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
rm -rf target/artifacts
|
||||
mkdir -p target/artifacts
|
||||
cp -R target/release/Graphite target/artifacts/Graphite
|
||||
|
||||
- name: 📦 Upload Windows bundle
|
||||
if: github.ref != 'refs/heads/master'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-windows-bundle
|
||||
path: target/artifacts
|
||||
|
||||
- name: 🔑 Azure login
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
enable-AzPSSession: true
|
||||
|
||||
- name: 🔏 Sign
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: azure/artifact-signing-action@v1
|
||||
with:
|
||||
endpoint: https://eus.codesigning.azure.net/
|
||||
signing-account-name: Graphite
|
||||
certificate-profile-name: Graphite
|
||||
files: |
|
||||
${{ github.workspace }}\target\artifacts\Graphite\Graphite.exe
|
||||
${{ github.workspace }}\target\artifacts\Graphite\libcef.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\chrome_elf.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\vulkan-1.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\dxcompiler.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\libEGL.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\libGLESv2.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\vk_swiftshader.dll
|
||||
file-digest: SHA256
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
correlation-id: ${{ github.sha }}
|
||||
|
||||
- name: ✅ Verify signatures
|
||||
if: github.ref == 'refs/heads/master'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$TargetDir = "target\artifacts\Graphite"
|
||||
|
||||
if (-not (Test-Path $TargetDir)) {
|
||||
throw "TargetDir not found: $TargetDir"
|
||||
}
|
||||
|
||||
$UnsignedOrBad = @()
|
||||
|
||||
Get-ChildItem -Path $TargetDir -Recurse -File -Include *.exe,*.dll | ForEach-Object {
|
||||
$sig = Get-AuthenticodeSignature -FilePath $_.FullName
|
||||
|
||||
if ($sig.Status -ne 'Valid') {
|
||||
$UnsignedOrBad += "$($_.FullName) (Status=$($sig.Status))"
|
||||
}
|
||||
}
|
||||
|
||||
if ($UnsignedOrBad.Count -gt 0) {
|
||||
Write-Host "Unsigned or invalid binaries detected:"
|
||||
$UnsignedOrBad | ForEach-Object {
|
||||
Write-Host "::error::$_"
|
||||
}
|
||||
|
||||
if ($env:GITHUB_STEP_SUMMARY) {
|
||||
"### ❌ Unsigned or invalid binaries detected" |
|
||||
Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
"" | Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
$UnsignedOrBad | ForEach-Object {
|
||||
"* `$_" | Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
}
|
||||
}
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "All binaries are signed and valid."
|
||||
|
||||
if ($env:GITHUB_STEP_SUMMARY) {
|
||||
"### ✅ All binaries are signed and valid" |
|
||||
Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
}
|
||||
|
||||
- name: 📦 Upload signed Windows bundle
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: graphite-windows-bundle-signed
|
||||
path: target/artifacts
|
||||
|
|
@ -0,0 +1,675 @@
|
|||
name: "Build"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
web:
|
||||
description: "Web"
|
||||
type: boolean
|
||||
windows:
|
||||
description: "Windows"
|
||||
type: boolean
|
||||
mac:
|
||||
description: "Mac"
|
||||
type: boolean
|
||||
linux:
|
||||
description: "Linux"
|
||||
type: boolean
|
||||
push_to_nix_cache:
|
||||
description: "Linux: push to Nix cache"
|
||||
type: boolean
|
||||
debug:
|
||||
description: "Debug build"
|
||||
type: boolean
|
||||
workflow_call:
|
||||
inputs:
|
||||
web:
|
||||
type: boolean
|
||||
windows:
|
||||
type: boolean
|
||||
mac:
|
||||
type: boolean
|
||||
linux:
|
||||
type: boolean
|
||||
push_to_nix_cache:
|
||||
type: boolean
|
||||
debug:
|
||||
type: boolean
|
||||
checkout_repo:
|
||||
type: string
|
||||
checkout_ref:
|
||||
type: string
|
||||
pr_number:
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
web:
|
||||
if: github.event_name == 'push' || inputs.web
|
||||
runs-on: [self-hosted, target/wasm]
|
||||
permissions:
|
||||
contents: write
|
||||
deployments: write
|
||||
pull-requests: write
|
||||
actions: write
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUSTC_WRAPPER: /usr/bin/sccache
|
||||
CARGO_INCREMENTAL: 0
|
||||
SCCACHE_DIR: /var/lib/github-actions/.cache
|
||||
INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="dev.graphite.art" data-api="https://graphite.art/visit/event" src="https://graphite.art/visit/script.hash.js"></script>
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ inputs.checkout_repo || github.repository }}
|
||||
ref: ${{ inputs.checkout_ref || '' }}
|
||||
|
||||
- name: 🗑 Clear wasm-bindgen cache
|
||||
run: rm -r ~/.cache/.wasm-pack || true
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: 🚧 Install build dependencies
|
||||
run: |
|
||||
cd frontend
|
||||
npm run setup
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: ✂ Replace template in <head> of index.html
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
sed -i "s|<!-- INDEX_HTML_HEAD_REPLACEMENT -->|$INDEX_HTML_HEAD_REPLACEMENT|" frontend/index.html
|
||||
|
||||
- name: 🌐 Build Graphite web code
|
||||
env:
|
||||
NODE_ENV: production
|
||||
run: mold -run cargo run build web${{ inputs.debug && ' debug' || '' }}
|
||||
|
||||
- name: 📤 Publish to Cloudflare Pages
|
||||
id: cloudflare
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
run: |
|
||||
MAX_ATTEMPTS=5
|
||||
DELAY=30
|
||||
for ATTEMPT in $(seq 1 $MAX_ATTEMPTS); do
|
||||
echo "Attempt $ATTEMPT of $MAX_ATTEMPTS..."
|
||||
if OUTPUT=$(npx wrangler@3 pages deploy "frontend/dist" --project-name="graphite-dev" --commit-dirty=true 2>&1); then
|
||||
URL=$(echo "$OUTPUT" | grep -oP 'https://[^\s]+\.pages\.dev' | head -1)
|
||||
echo "url=$URL" >> "$GITHUB_OUTPUT"
|
||||
echo "Published successfully: $URL"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $ATTEMPT failed:"
|
||||
echo "$OUTPUT"
|
||||
if [ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]; then
|
||||
echo "Retrying in ${DELAY}s..."
|
||||
sleep $DELAY
|
||||
DELAY=$((DELAY * 3))
|
||||
fi
|
||||
done
|
||||
echo "All $MAX_ATTEMPTS Cloudflare Pages publish attempts failed."
|
||||
exit 1
|
||||
|
||||
- name: 💬 Comment with the build link
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CF_URL: ${{ steps.cloudflare.outputs.url }}
|
||||
run: |
|
||||
if [ -z "$CF_URL" ]; then
|
||||
echo "No Cloudflare URL available, skipping comment."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
COMMENT_BODY="| 📦 **Web Build Complete for** $(git rev-parse HEAD) |
|
||||
|-|
|
||||
| $CF_URL |"
|
||||
|
||||
if [ "${{ github.event_name }}" = "push" ]; then
|
||||
# Comment on the commit hash page
|
||||
gh api \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
/repos/${{ github.repository }}/commits/$(git rev-parse HEAD)/comments \
|
||||
-f body="$COMMENT_BODY"
|
||||
else
|
||||
# Comment on the PR (use provided PR number from !build, or look it up by branch name)
|
||||
PR_NUMBER="${{ inputs.pr_number }}"
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
gh pr comment "$PR_NUMBER" --repo ${{ github.repository }} --body "$COMMENT_BODY"
|
||||
else
|
||||
echo "No open PR found, skipping comment."
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: ✂ Strip analytics script from built output for clean artifact
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
sed -i "s|$INDEX_HTML_HEAD_REPLACEMENT||" frontend/dist/index.html
|
||||
|
||||
- name: 📦 Upload web bundle artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-web-bundle
|
||||
path: frontend/dist
|
||||
|
||||
- name: 📃 Generate code documentation info for website
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
cd tools/editor-message-tree
|
||||
cargo run
|
||||
cd ../..
|
||||
mkdir -p artifacts-generated
|
||||
mv website/generated/hierarchical_message_system_tree.txt artifacts-generated/hierarchical_message_system_tree.txt
|
||||
|
||||
- name: 💿 Obtain cache of auto-generated code docs artifacts, to check if they've changed
|
||||
if: github.event_name == 'push'
|
||||
id: cache-website-code-docs
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: artifacts
|
||||
key: website-code-docs
|
||||
|
||||
- name: 🔍 Check if auto-generated code docs artifacts changed
|
||||
if: github.event_name == 'push'
|
||||
id: website-code-docs-changed
|
||||
run: |
|
||||
if ! diff --brief --recursive artifacts-generated artifacts; then
|
||||
echo "Auto-generated code docs artifacts have changed."
|
||||
rm -rf artifacts
|
||||
mv artifacts-generated artifacts
|
||||
echo "changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Auto-generated code docs artifacts have not changed."
|
||||
rm -rf artifacts
|
||||
rm -rf artifacts-generated
|
||||
fi
|
||||
|
||||
- name: 💾 Save cache of auto-generated code docs artifacts
|
||||
if: github.event_name == 'push' && steps.website-code-docs-changed.outputs.changed == 'true'
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: artifacts
|
||||
key: ${{ steps.cache-website-code-docs.outputs.cache-primary-key }}
|
||||
|
||||
- name: ♻️ Trigger website rebuild if the auto-generated code docs artifacts have changed
|
||||
if: github.event_name == 'push' && steps.website-code-docs-changed.outputs.changed == 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
rm -rf artifacts
|
||||
gh workflow run website.yml --ref master
|
||||
|
||||
windows:
|
||||
if: github.event_name == 'push' || inputs.windows
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
WASM_BINDGEN_CLI_VERSION: "0.2.100"
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ inputs.checkout_repo || github.repository }}
|
||||
ref: ${{ inputs.checkout_ref || '' }}
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: 💾 Set up Cargo cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
${{ env.USERPROFILE }}\.cargo\registry
|
||||
${{ env.USERPROFILE }}\.cargo\git
|
||||
target
|
||||
key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: npm
|
||||
cache-dependency-path: |
|
||||
package-lock.json
|
||||
frontend/package-lock.json
|
||||
|
||||
- name: 📦 Install Cargo-binstall
|
||||
uses: cargo-bins/cargo-binstall@main
|
||||
|
||||
- name: 🚧 Install native dependencies
|
||||
shell: pwsh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
BINSTALL_DISABLE_TELEMETRY: "true"
|
||||
run: |
|
||||
winget install --id LLVM.LLVM -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id Kitware.CMake -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id OpenSSL.OpenSSL -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id WebAssembly.Binaryen -e --accept-package-agreements --accept-source-agreements
|
||||
winget install --id GnuWin32.PkgConfig -e --accept-package-agreements --accept-source-agreements
|
||||
|
||||
"OPENSSL_DIR=C:\Program Files\OpenSSL-Win64" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
"PKG_CONFIG_PATH=C:\Program Files\OpenSSL-Win64\lib\pkgconfig" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
cargo binstall --no-confirm --force wasm-pack
|
||||
cargo binstall --no-confirm --force cargo-about
|
||||
cargo binstall --no-confirm --force "wasm-bindgen-cli@$env:WASM_BINDGEN_CLI_VERSION"
|
||||
|
||||
- name: 🏗 Build Windows bundle
|
||||
shell: bash # `cargo-about` refuses to run in powershell
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
run: cargo run build desktop${{ inputs.debug && ' debug' || '' }}
|
||||
|
||||
- name: 📁 Stage artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
PROFILE=${{ inputs.debug && 'debug' || 'release' }}
|
||||
rm -rf target/artifacts
|
||||
mkdir -p target/artifacts
|
||||
cp -R target/$PROFILE/Graphite target/artifacts/Graphite
|
||||
|
||||
- name: 📦 Upload Windows bundle
|
||||
if: github.event_name != 'push'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-windows-bundle
|
||||
path: target/artifacts
|
||||
|
||||
- name: 💬 Comment artifact link on PR
|
||||
if: github.event_name != 'push'
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
ARTIFACT_URL=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts --jq '.artifacts[] | select(.name == "graphite-windows-bundle") | .archive_download_url')
|
||||
PR_NUMBER="${{ inputs.pr_number }}"
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
|
||||
fi
|
||||
if [ -n "$PR_NUMBER" ] && [ -n "$ARTIFACT_URL" ]; then
|
||||
gh pr comment "$PR_NUMBER" --repo ${{ github.repository }} --body "| 📦 **Windows Build Complete for** $(git rev-parse HEAD) |
|
||||
|-|
|
||||
| [Download artifact]($ARTIFACT_URL) |"
|
||||
fi
|
||||
|
||||
- name: 🔑 Azure login
|
||||
if: github.event_name == 'push'
|
||||
uses: azure/login@v1
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
enable-AzPSSession: true
|
||||
|
||||
- name: 🔏 Sign
|
||||
if: github.event_name == 'push'
|
||||
uses: azure/artifact-signing-action@v1
|
||||
with:
|
||||
endpoint: https://eus.codesigning.azure.net/
|
||||
signing-account-name: Graphite
|
||||
certificate-profile-name: Graphite
|
||||
files: |
|
||||
${{ github.workspace }}\target\artifacts\Graphite\Graphite.exe
|
||||
${{ github.workspace }}\target\artifacts\Graphite\libcef.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\chrome_elf.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\vulkan-1.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\dxcompiler.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\libEGL.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\libGLESv2.dll
|
||||
${{ github.workspace }}\target\artifacts\Graphite\vk_swiftshader.dll
|
||||
file-digest: SHA256
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
correlation-id: ${{ github.sha }}
|
||||
|
||||
- name: ✅ Verify signatures
|
||||
if: github.event_name == 'push'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$TargetDir = "target\artifacts\Graphite"
|
||||
|
||||
if (-not (Test-Path $TargetDir)) {
|
||||
throw "TargetDir not found: $TargetDir"
|
||||
}
|
||||
|
||||
$UnsignedOrBad = @()
|
||||
|
||||
Get-ChildItem -Path $TargetDir -Recurse -File -Include *.exe,*.dll | ForEach-Object {
|
||||
$sig = Get-AuthenticodeSignature -FilePath $_.FullName
|
||||
|
||||
if ($sig.Status -ne 'Valid') {
|
||||
$UnsignedOrBad += "$($_.FullName) (Status=$($sig.Status))"
|
||||
}
|
||||
}
|
||||
|
||||
if ($UnsignedOrBad.Count -gt 0) {
|
||||
Write-Host "Unsigned or invalid binaries detected:"
|
||||
$UnsignedOrBad | ForEach-Object {
|
||||
Write-Host "::error::$_"
|
||||
}
|
||||
|
||||
if ($env:GITHUB_STEP_SUMMARY) {
|
||||
"### ❌ Unsigned or invalid binaries detected" |
|
||||
Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
"" | Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
$UnsignedOrBad | ForEach-Object {
|
||||
"* `$_" | Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
}
|
||||
}
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "All binaries are signed and valid."
|
||||
|
||||
if ($env:GITHUB_STEP_SUMMARY) {
|
||||
"### ✅ All binaries are signed and valid" |
|
||||
Out-File $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
|
||||
}
|
||||
|
||||
- name: 📦 Upload signed Windows bundle
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-windows-bundle-signed
|
||||
path: target/artifacts
|
||||
|
||||
mac:
|
||||
if: github.event_name == 'push' || inputs.mac
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
WASM_BINDGEN_CLI_VERSION: "0.2.100"
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ inputs.checkout_repo || github.repository }}
|
||||
ref: ${{ inputs.checkout_ref || '' }}
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: 💾 Set up Cargo cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: npm
|
||||
cache-dependency-path: |
|
||||
package-lock.json
|
||||
frontend/package-lock.json
|
||||
|
||||
- name: 🚧 Install native dependencies
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
BINSTALL_DISABLE_TELEMETRY: "true"
|
||||
run: |
|
||||
brew update
|
||||
brew install \
|
||||
pkg-config \
|
||||
openssl@3 \
|
||||
binaryen \
|
||||
llvm \
|
||||
cargo-binstall
|
||||
|
||||
echo "OPENSSL_DIR=$(brew --prefix openssl@3)" >> $GITHUB_ENV
|
||||
echo "PKG_CONFIG_PATH=$(brew --prefix openssl@3)/lib/pkgconfig" >> $GITHUB_ENV
|
||||
echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH
|
||||
|
||||
cargo binstall --no-confirm --force wasm-pack
|
||||
cargo binstall --no-confirm --force cargo-about
|
||||
cargo binstall --no-confirm --force "wasm-bindgen-cli@${WASM_BINDGEN_CLI_VERSION}"
|
||||
|
||||
- name: 🏗 Build Mac bundle
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
run: cargo run build desktop${{ inputs.debug && ' debug' || '' }}
|
||||
|
||||
- name: 📁 Stage artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
PROFILE=${{ inputs.debug && 'debug' || 'release' }}
|
||||
rm -rf target/artifacts
|
||||
mkdir -p target/artifacts
|
||||
cp -R target/$PROFILE/Graphite.app target/artifacts/Graphite.app
|
||||
|
||||
- name: 📦 Upload Mac bundle
|
||||
if: github.event_name != 'push'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-mac-bundle
|
||||
path: target/artifacts
|
||||
|
||||
- name: 💬 Comment artifact link on PR
|
||||
if: github.event_name != 'push'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
ARTIFACT_URL=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts --jq '.artifacts[] | select(.name == "graphite-mac-bundle") | .archive_download_url')
|
||||
PR_NUMBER="${{ inputs.pr_number }}"
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
|
||||
fi
|
||||
if [ -n "$PR_NUMBER" ] && [ -n "$ARTIFACT_URL" ]; then
|
||||
gh pr comment "$PR_NUMBER" --repo ${{ github.repository }} --body "| 📦 **Mac Build Complete for** $(git rev-parse HEAD) |
|
||||
|-|
|
||||
| [Download artifact]($ARTIFACT_URL) |"
|
||||
fi
|
||||
|
||||
- name: 🔏 Sign and notarize (preparation)
|
||||
if: github.event_name == 'push'
|
||||
env:
|
||||
APPLE_CERT_BASE64: ${{ secrets.APPLE_CERT_BASE64 }}
|
||||
APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
|
||||
run: |
|
||||
mkdir -p .sign
|
||||
echo "$APPLE_CERT_BASE64" | base64 --decode > .sign/certificate.p12
|
||||
|
||||
security create-keychain -p "" .sign/main.keychain
|
||||
security default-keychain -s .sign/main.keychain
|
||||
security unlock-keychain -p "" .sign/main.keychain
|
||||
security set-keychain-settings -t 3600 -u .sign/main.keychain
|
||||
|
||||
security import .sign/certificate.p12 -k .sign/main.keychain -P "$APPLE_CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "" .sign/main.keychain
|
||||
|
||||
cat > .sign/entitlements.plist <<'EOF'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
- name: 🔏 Sign and notarize
|
||||
if: github.event_name == 'push'
|
||||
env:
|
||||
APPLE_EMAIL: ${{ secrets.APPLE_EMAIL }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_CERT_NAME: ${{ secrets.APPLE_CERT_NAME }}
|
||||
run: |
|
||||
CERTIFICATE="$APPLE_CERT_NAME"
|
||||
ENTITLEMENTS=".sign/entitlements.plist"
|
||||
APP_PATH="target/artifacts/Graphite.app"
|
||||
ZIP_PATH=".sign/Graphite.zip"
|
||||
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Graphite Helper.app"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Graphite Helper (GPU).app"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Graphite Helper (Renderer).app"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libcef_sandbox.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libEGL.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libGLESv2.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libvk_swiftshader.dylib"
|
||||
codesign --force --options runtime --entitlements "$ENTITLEMENTS" --sign "$CERTIFICATE" "$APP_PATH" --deep
|
||||
|
||||
codesign --verify --deep --strict --verbose=4 "$APP_PATH"
|
||||
|
||||
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
|
||||
xcrun notarytool submit "$ZIP_PATH" --wait --apple-id "$APPLE_EMAIL" --team-id "$APPLE_TEAM_ID" --password "$APPLE_PASSWORD"
|
||||
rm "$ZIP_PATH"
|
||||
|
||||
xcrun stapler staple -v "$APP_PATH"
|
||||
|
||||
spctl -a -vv "$APP_PATH"
|
||||
|
||||
- name: 📦 Upload signed Mac bundle
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-mac-bundle-signed
|
||||
path: target/artifacts
|
||||
|
||||
linux:
|
||||
if: github.event_name == 'push' || inputs.linux
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ inputs.checkout_repo || github.repository }}
|
||||
ref: ${{ inputs.checkout_ref || '' }}
|
||||
|
||||
- name: ❄ Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
|
||||
- name: 🗑 Free disk space
|
||||
run: sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache
|
||||
|
||||
- name: 📦 Build Nix package
|
||||
run: nix build .#graphite${{ inputs.debug && '-dev' || '' }} --no-link --print-out-paths
|
||||
|
||||
- name: 📤 Push to Nix cache
|
||||
if: (github.event_name == 'push' || inputs.push_to_nix_cache) && !inputs.debug
|
||||
env:
|
||||
NIX_CACHE_AUTH_TOKEN: ${{ secrets.NIX_CACHE_AUTH_TOKEN }}
|
||||
run: |
|
||||
nix run nixpkgs#cachix -- authtoken $NIX_CACHE_AUTH_TOKEN
|
||||
nix build --no-link --print-out-paths | nix run nixpkgs#cachix -- push graphite
|
||||
|
||||
- name: 🏗 Build Linux bundle
|
||||
run: nix build .#graphite${{ inputs.debug && '-dev' || '' }}-bundle.tar.xz && cp ./result ./graphite-linux-bundle.tar.xz
|
||||
|
||||
- name: 📦 Upload Linux bundle
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-linux-bundle
|
||||
path: graphite-linux-bundle.tar.xz
|
||||
compression-level: 0
|
||||
|
||||
- name: 💬 Comment artifact link on PR
|
||||
if: github.event_name != 'push'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
ARTIFACT_URL=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts --jq '.artifacts[] | select(.name == "graphite-linux-bundle") | .archive_download_url')
|
||||
PR_NUMBER="${{ inputs.pr_number }}"
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
|
||||
fi
|
||||
if [ -n "$PR_NUMBER" ] && [ -n "$ARTIFACT_URL" ]; then
|
||||
gh pr comment "$PR_NUMBER" --repo ${{ github.repository }} --body "| 📦 **Linux Build Complete for** $(git rev-parse HEAD) |
|
||||
|-|
|
||||
| [Download artifact]($ARTIFACT_URL) |"
|
||||
fi
|
||||
|
||||
- name: 🔧 Install Flatpak tooling
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y flatpak flatpak-builder
|
||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
- name: 🏗 Build Flatpak
|
||||
run: |
|
||||
nix build .#graphite-flatpak-manifest
|
||||
|
||||
rm -rf .flatpak
|
||||
mkdir -p .flatpak
|
||||
|
||||
cp ./result .flatpak/manifest.json
|
||||
|
||||
cd .flatpak
|
||||
mkdir -p repo
|
||||
|
||||
flatpak-builder --user --force-clean --install-deps-from=flathub --repo=repo build ./manifest.json
|
||||
|
||||
flatpak build-bundle repo Graphite.flatpak art.graphite.Graphite --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
- name: 📦 Upload Flatpak package
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: graphite-flatpak
|
||||
path: .flatpak/Graphite.flatpak
|
||||
compression-level: 0
|
||||
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🔒 Check crate security advisories for root workspace
|
||||
uses: EmbarkStudios/cargo-deny-action@v2
|
||||
|
|
|
|||
|
|
@ -8,48 +8,6 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
# Rust format check on GitHub runner
|
||||
rust-fmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🚦 Check if CI can be skipped
|
||||
id: skip-check
|
||||
uses: cariad-tech/merge-queue-ci-skipper@main
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
if: steps.skip-check.outputs.skip-check != 'true'
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
rustflags: ""
|
||||
components: rustfmt
|
||||
|
||||
- name: 🔬 Check Rust formatting
|
||||
if: steps.skip-check.outputs.skip-check != 'true'
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
# License compatibility check on GitHub runner
|
||||
cargo-deny:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 📜 Check crate license compatibility for root workspace
|
||||
uses: EmbarkStudios/cargo-deny-action@v2
|
||||
with:
|
||||
command: check bans licenses sources
|
||||
|
||||
- name: 📜 Check crate license compatibility for /libraries/rawkit
|
||||
uses: EmbarkStudios/cargo-deny-action@v2
|
||||
with:
|
||||
command: check bans licenses sources
|
||||
manifest-path: libraries/rawkit/Cargo.toml
|
||||
|
||||
# Build the web app on the self-hosted wasm runner
|
||||
build:
|
||||
runs-on: [self-hosted, target/wasm]
|
||||
|
|
@ -65,7 +23,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🚦 Check if CI can be skipped
|
||||
id: skip-check
|
||||
|
|
@ -77,7 +35,7 @@ jobs:
|
|||
|
||||
- name: 🟢 Install Node.js
|
||||
if: steps.skip-check.outputs.skip-check != 'true'
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
|
|
@ -93,6 +51,7 @@ jobs:
|
|||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
|
|
@ -134,7 +93,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🚦 Check if CI can be skipped
|
||||
id: skip-check
|
||||
|
|
@ -146,6 +105,7 @@ jobs:
|
|||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
|
||||
- name: 🦀 Fetch Rust dependencies
|
||||
|
|
@ -159,3 +119,46 @@ jobs:
|
|||
RUSTFLAGS: -Dwarnings
|
||||
run: |
|
||||
mold -run cargo test --all-features
|
||||
|
||||
# Rust format check on GitHub runner
|
||||
rust-fmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🚦 Check if CI can be skipped
|
||||
id: skip-check
|
||||
uses: cariad-tech/merge-queue-ci-skipper@main
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
if: steps.skip-check.outputs.skip-check != 'true'
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
components: rustfmt
|
||||
|
||||
- name: 🔬 Check Rust formatting
|
||||
if: steps.skip-check.outputs.skip-check != 'true'
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
# License compatibility check on GitHub runner
|
||||
check-licenses:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 📜 Check crate license compatibility for root workspace
|
||||
uses: EmbarkStudios/cargo-deny-action@v2
|
||||
with:
|
||||
command: check bans licenses sources
|
||||
|
||||
- name: 📜 Check crate license compatibility for /libraries/rawkit
|
||||
uses: EmbarkStudios/cargo-deny-action@v2
|
||||
with:
|
||||
command: check bans licenses sources
|
||||
manifest-path: libraries/rawkit/Cargo.toml
|
||||
|
|
|
|||
|
|
@ -1,158 +1,137 @@
|
|||
# USAGE:
|
||||
# After reviewing the code, core team members may comment on a PR with the exact text:
|
||||
# - `!build-debug` to build with debug symbols and optimizations disabled
|
||||
# - `!build` to build without debug symbols and optimizations enabled
|
||||
# The comment may not contain any other text, not even whitespace or newlines.
|
||||
# After reviewing the code, core team members may comment on a PR with `!build` followed by optional `<target>` and `<profile>` arguments.
|
||||
# This matches the syntax of the `cargo run build` CLI command, but allows platforms to be specified.
|
||||
#
|
||||
# `<target>`: `web` (default), `desktop` (all platforms), or `desktop:<platforms>` (subset of `windows+mac+linux`)
|
||||
# `<profile>`: `release` (default) or `debug`
|
||||
#
|
||||
# Examples:
|
||||
# - !build
|
||||
# - !build debug
|
||||
# - !build desktop
|
||||
# - !build desktop:windows+mac
|
||||
# - !build desktop:linux debug
|
||||
name: "!build PR Command"
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
setup:
|
||||
# Command should be limited to core team members (those in the organization) for security.
|
||||
# From the GitHub Actions docs:
|
||||
# author_association = 'MEMBER': Author is a member of the organization that owns the repository.
|
||||
if: >
|
||||
github.event.issue.pull_request &&
|
||||
github.event.comment.author_association == 'MEMBER' &&
|
||||
(github.event.comment.body == '!build-debug' || github.event.comment.body == '!build')
|
||||
runs-on: self-hosted
|
||||
startsWith(github.event.comment.body, '!build')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
pull-requests: write
|
||||
env:
|
||||
RUSTC_WRAPPER: /usr/bin/sccache
|
||||
CARGO_INCREMENTAL: 0
|
||||
SCCACHE_DIR: /var/lib/github-actions/.cache
|
||||
outputs:
|
||||
repo: ${{ steps.pr_info.outputs.repo }}
|
||||
ref: ${{ steps.pr_info.outputs.ref }}
|
||||
web: ${{ steps.pr_info.outputs.web }}
|
||||
windows: ${{ steps.pr_info.outputs.windows }}
|
||||
mac: ${{ steps.pr_info.outputs.mac }}
|
||||
linux: ${{ steps.pr_info.outputs.linux }}
|
||||
debug: ${{ steps.pr_info.outputs.debug }}
|
||||
|
||||
steps:
|
||||
- name: 🔎 Find branch for this PR
|
||||
id: commit_info
|
||||
- name: 🔎 Parse command, find branch, and set build flags
|
||||
id: pr_info
|
||||
run: |
|
||||
RESPONSE=$(curl -L -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.issue.number }})
|
||||
REPO=$(echo $RESPONSE | jq -r '.head.repo.full_name')
|
||||
REF=$(echo $RESPONSE | jq -r '.head.ref')
|
||||
SHA=$(echo $RESPONSE | jq -r '.head.sha')
|
||||
echo "repo=$REPO" >> $GITHUB_OUTPUT
|
||||
echo "ref=$REF" >> $GITHUB_OUTPUT
|
||||
echo "sha=$SHA" >> $GITHUB_OUTPUT
|
||||
COMMENT="${{ github.event.comment.body }}"
|
||||
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ steps.commit_info.outputs.repo }}
|
||||
ref: ${{ steps.commit_info.outputs.ref }}
|
||||
# Split into space-separated words
|
||||
read -ra WORDS <<< "$COMMENT"
|
||||
|
||||
- name: 🗑 Clear wasm-bindgen cache
|
||||
continue-on-error: true
|
||||
run: rm -r ~/.cache/.wasm-pack
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: 🚧 Install build dependencies
|
||||
run: |
|
||||
cd frontend
|
||||
npm run setup
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
- name: ✂ Replace template in <head> of index.html
|
||||
env:
|
||||
INDEX_HTML_HEAD_REPLACEMENT: ""
|
||||
run: |
|
||||
# Remove the INDEX_HTML_HEAD_REPLACEMENT environment variable for build links (not master deploys)
|
||||
sed -i "s|<!-- INDEX_HTML_HEAD_REPLACEMENT -->|$INDEX_HTML_HEAD_REPLACEMENT|" frontend/index.html
|
||||
|
||||
- name: ⌨ Set build command based on comment
|
||||
id: build_command
|
||||
run: |
|
||||
if [[ "${{ github.event.comment.body }}" == "!build-debug" ]]; then
|
||||
echo "command=build web debug" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ github.event.comment.body }}" == "!build" ]]; then
|
||||
echo "command=build web" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Failed to detect if the build command written in the comment should have been '!build-debug', or '!build'" >> $GITHUB_OUTPUT
|
||||
# First word must be "!build"
|
||||
if [[ "${WORDS[0]}" != "!build" ]]; then
|
||||
echo "::error::Expected comment to start with !build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: 💬 Comment Actions run link
|
||||
id: comment_actions_run_link
|
||||
uses: actions/github-script@v6
|
||||
# Initialize build flags (web defaults to true, matching the CLI default target)
|
||||
WEB="true"
|
||||
WINDOWS="false"
|
||||
MAC="false"
|
||||
LINUX="false"
|
||||
DEBUG="false"
|
||||
|
||||
# Parse target (optional, defaults to `web` if omitted)
|
||||
IDX=1
|
||||
case "${WORDS[$IDX]:-}" in
|
||||
# Target: `web` enables just the web build (already the default, but accepted explicitly)
|
||||
"web")
|
||||
((IDX++)) ;;
|
||||
# Target: `desktop` enables all three desktop platforms
|
||||
"desktop")
|
||||
WEB="false"; WINDOWS="true"; MAC="true"; LINUX="true"; ((IDX++)) ;;
|
||||
# Target: `desktop:<platforms>` enables a subset of desktop platforms, split by `+`
|
||||
desktop:*)
|
||||
WEB="false"
|
||||
PLATFORMS="${WORDS[$IDX]#desktop:}"
|
||||
IFS='+' read -ra PARTS <<< "$PLATFORMS"
|
||||
for PART in "${PARTS[@]}"; do
|
||||
case "$PART" in
|
||||
"windows") WINDOWS="true" ;;
|
||||
"mac") MAC="true" ;;
|
||||
"linux") LINUX="true" ;;
|
||||
*) echo "::error::Unrecognized platform: $PART"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
((IDX++))
|
||||
;;
|
||||
esac
|
||||
|
||||
# Parse profile (optional, defaults to `release` if omitted)
|
||||
case "${WORDS[$IDX]:-}" in
|
||||
"debug") DEBUG="true"; ((IDX++)) ;;
|
||||
"release") ((IDX++)) ;;
|
||||
esac
|
||||
|
||||
# Reject any unexpected trailing words
|
||||
if [[ $IDX -lt ${#WORDS[@]} ]]; then
|
||||
echo "::error::Unexpected argument: ${WORDS[$IDX]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Write parsed build flags to job outputs
|
||||
echo "web=$WEB" >> $GITHUB_OUTPUT
|
||||
echo "windows=$WINDOWS" >> $GITHUB_OUTPUT
|
||||
echo "mac=$MAC" >> $GITHUB_OUTPUT
|
||||
echo "linux=$LINUX" >> $GITHUB_OUTPUT
|
||||
echo "debug=$DEBUG" >> $GITHUB_OUTPUT
|
||||
|
||||
# Fetch the PR's head branch and repo (needed for forked PRs where the code lives in another repo)
|
||||
RESPONSE=$(curl -L -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.issue.number }})
|
||||
echo "repo=$(echo $RESPONSE | jq -r '.head.repo.full_name')" >> $GITHUB_OUTPUT
|
||||
echo "ref=$(echo $RESPONSE | jq -r '.head.ref')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: 💬 Edit comment with workflow run link
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.updateComment({
|
||||
comment_id: ${{ github.event.comment.id }},
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: '!build ([Run ID ' + context.runId + '](https://github.com/GraphiteEditor/Graphite/actions/runs/' + context.runId + '))'
|
||||
body: '${{ github.event.comment.body }} ([Run ID ' + context.runId + '](https://github.com/GraphiteEditor/Graphite/actions/runs/' + context.runId + '))'
|
||||
});
|
||||
|
||||
- name: 🌐 Build Graphite web code
|
||||
env:
|
||||
NODE_ENV: production
|
||||
if: ${{ success() || failure()}}
|
||||
run: mold -run cargo run ${{ steps.build_command.outputs.command }}
|
||||
|
||||
- name: ❗ Warn on build failure
|
||||
if: ${{ failure() }}
|
||||
uses: actions/github-script@v6
|
||||
invoke-build:
|
||||
needs: setup
|
||||
uses: ./.github/workflows/build.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: 'The build process has failed. Please check the [build logs](https://github.com/GraphiteEditor/Graphite/actions/runs/' + context.runId + ') for details.'
|
||||
});
|
||||
|
||||
- name: 📤 Publish to Cloudflare Pages
|
||||
id: cloudflare
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
run: |
|
||||
if OUTPUT=$(npx wrangler@3 pages deploy "frontend/dist" --project-name="graphite-dev" --commit-dirty=true 2>&1); then
|
||||
URL=$(echo "$OUTPUT" | grep -oP 'https://[^\s]+\.pages\.dev' | tail -1)
|
||||
echo "url=$URL" >> "$GITHUB_OUTPUT"
|
||||
echo "Published successfully: $URL"
|
||||
else
|
||||
echo "$OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: ❗ Warn on publish failure
|
||||
if: ${{ failure() }}
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: 'The deployment to Cloudflare Pages has failed. Please check the [build logs](https://github.com/GraphiteEditor/Graphite/actions/runs/' + context.runId + ') for details.'
|
||||
});
|
||||
|
||||
- name: 💬 Comment build link
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: '| 📦 **Build Complete for** ${{ steps.commit_info.outputs.sha }} |\n|-|\n| ${{ steps.cloudflare.outputs.url }} |'
|
||||
})
|
||||
web: ${{ needs.setup.outputs.web == 'true' }}
|
||||
windows: ${{ needs.setup.outputs.windows == 'true' }}
|
||||
mac: ${{ needs.setup.outputs.mac == 'true' }}
|
||||
linux: ${{ needs.setup.outputs.linux == 'true' }}
|
||||
debug: ${{ needs.setup.outputs.debug == 'true' }}
|
||||
checkout_repo: ${{ needs.setup.outputs.repo }}
|
||||
checkout_ref: ${{ needs.setup.outputs.ref }}
|
||||
pr_number: ${{ github.event.issue.number }}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
|
||||
- name: Cache iai-callgrind binary
|
||||
id: cache-iai
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.cargo/bin/iai-callgrind-runner
|
||||
key: ${{ runner.os }}-iai-callgrind-runner-0.16.1
|
||||
|
|
@ -65,7 +65,7 @@ jobs:
|
|||
|
||||
- name: Cache benchmark baselines
|
||||
id: cache-benchmark-baselines
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: target/iai
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-${{ steps.cpu-info.outputs.cpu-hash }}-benchmark-baselines-master-${{ steps.master-sha.outputs.sha }}
|
||||
|
|
|
|||
|
|
@ -26,13 +26,14 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🦀 Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
|
||||
- name: 📦 Run sccache-cache
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
contents: read
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: ❄ Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
name: "Editor: Production (Latest Stable)"
|
||||
name: "Release"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -22,13 +22,13 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🗑 Clear wasm-bindgen cache
|
||||
run: rm -r ~/.cache/.wasm-pack
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
|
|
@ -42,6 +42,7 @@ jobs:
|
|||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
cache: false
|
||||
rustflags: ""
|
||||
target: wasm32-unknown-unknown
|
||||
|
||||
|
|
@ -24,10 +24,10 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: 📥 Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🟢 Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ jobs:
|
|||
|
||||
- name: 💿 Obtain cache of auto-generated code docs artifacts
|
||||
id: cache-website-code-docs
|
||||
uses: actions/cache/restore@v4
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: artifacts
|
||||
key: website-code-docs
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ in
|
|||
graphite-dev = (lib.call ./pkgs/graphite.nix) { dev = true; };
|
||||
graphite-raster-nodes-shaders = lib.call ./pkgs/graphite-raster-nodes-shaders.nix;
|
||||
graphite-branding = lib.call ./pkgs/graphite-branding.nix;
|
||||
graphite-bundle = lib.call ./pkgs/graphite-bundle.nix;
|
||||
graphite-bundle = (lib.call ./pkgs/graphite-bundle.nix) { };
|
||||
graphite-dev-bundle = (lib.call ./pkgs/graphite-bundle.nix) { graphite = graphite-dev; };
|
||||
graphite-flatpak-manifest = lib.call ./pkgs/graphite-flatpak-manifest.nix;
|
||||
|
||||
# TODO: graphene-cli = lib.call ./pkgs/graphene-cli.nix;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
system,
|
||||
...
|
||||
}:
|
||||
{
|
||||
graphite ? self.packages.${system}.graphite,
|
||||
}:
|
||||
let
|
||||
bundle =
|
||||
{
|
||||
|
|
@ -13,7 +16,6 @@ let
|
|||
}:
|
||||
(
|
||||
let
|
||||
graphite = self.packages.${system}.graphite;
|
||||
tar = if compression == null then archive else true;
|
||||
nameArchiveSuffix = if tar then ".tar" else "";
|
||||
nameCompressionSuffix = if compression == null then "" else "." + compression;
|
||||
|
|
|
|||
Loading…
Reference in New Issue