Presto organization's CI/CD is entirely based on GitHub Actions, covering builds, testing, security scanning, releases, and cross-repo synchronization.
Organization-Level Overview
Cross-Repo Trigger Chain
Repository CI Coverage
| Repository | Workflow | Trigger | Description |
|---|---|---|---|
| Presto | release.yml | tag v* | Main app multi-platform build + release |
| Presto | build-showcase.yml | push main (showcase paths) | Build Showcase static files |
| Presto | security-scan.yml | weekly Monday / PR / manual | Go vulncheck + npm audit |
| presto-official-templates | release.yml | tag v* | Smart incremental build for official templates |
| presto-template-starter-go | release.yml | tag v* | Go template 6-platform build |
| presto-template-starter-rust | release.yml | tag v* | Rust template 6-platform build |
| presto-template-starter-typescript | release.yml | tag v* | TS template 6-platform build |
| template-registry | update-registry.yml | daily 08:00 UTC / manual | Discover + compile + deploy templates |
| template-registry | check-versions.yml | daily 08:30 UTC / manual | Detect new verified template versions |
| template-registry | build-verified.yml | push main (verified-templates.json) | Compile verified templates |
| Presto-homepage | sync-release.yml | repository_dispatch / manual | Sync Presto releases to website |
| Presto-homepage | sync-showcase.yml | repository_dispatch / manual | Sync Showcase to website |
| create-presto-template | None | -- | CLI scaffolding tool, no build artifacts |
| registry-deploy | None | -- | Pure static deploy repo, pushed by registry CI |
| Presto-doc | None | -- | Documentation project, no CI needed |
Presto Main App Release Pipeline
Job Flow Diagram
release.yml is triggered by pushing a tag v*, containing the following Jobs:
Build Matrix
| Platform | Arch | Runner | Package Format | Notes |
|---|---|---|---|---|
| macOS | arm64 | macos-latest | DMG | Native compilation |
| macOS | amd64 | macos-latest | DMG | Cross-compilation |
| Windows | amd64 | windows-latest | ZIP | MSYS2 MinGW gcc |
| Windows | arm64 | windows-latest | ZIP | llvm-mingw cross-compile |
| Linux | amd64 | ubuntu-22.04 | tar.gz | Native compilation |
| Linux | arm64 | ubuntu-22.04-arm | tar.gz | ARM native Runner |
| Docker | amd64 | ubuntu-latest | OCI image | Pushed to ghcr.io |
| Docker | arm64 | ubuntu-24.04-arm | OCI image | Pushed to ghcr.io |
All desktop build artifacts include the Presto main program and the Typst CLI (v0.14.2). Docker images are pushed to ghcr.io/presto-io/presto, merged into a multi-architecture manifest via the merge-docker Job.
macOS Code Signing and Notarization
The signing process is implemented by packaging/macos/codesign.sh, signing from inside out:
- Sign the embedded Typst binary (
Contents/Resources/typst) - Sign the main program (
Contents/MacOS/Presto) - Sign the entire
.appbundle - Verify with
codesign --verify --deep --strict
In CI, the P12 certificate is imported into a temporary Keychain via Secrets. After signing, the app is submitted for Apple notarization (xcrun notarytool submit), and upon approval, the ticket is stapled (xcrun stapler staple).
Current status: macOS code signing requires Apple Developer Program ($99/year). When signing Secrets are not configured, CI automatically falls back to ad-hoc signing (
-s -), and users need to runxattr -cr Presto.appto bypass Gatekeeper.
Windows arm64 Cross-Compilation
The Windows arm64 build uses the llvm-mingw toolchain (aarch64-w64-mingw32-gcc) to cross-compile on an x64 Runner. The toolchain is cached via actions/cache, with SHA256 checksum verification on first download.
Security Scanning
security-scan.yml contains two independent Jobs:
| Job | Tool | Scan Scope | Trigger Condition |
|---|---|---|---|
| go-vulncheck | govulncheck | Go dependency vulnerabilities | Weekly Monday / PR modifying go.mod |
| npm-audit | npm audit | Frontend dependency vulnerabilities | Weekly Monday / PR modifying package-lock.json |
Both Jobs can be manually triggered via workflow_dispatch.
Showcase Build
build-showcase.yml triggers on push to main when showcase-related paths change. After building the frontend static files, it extracts the showcase/ and _app/ directories, uploads them as an artifact, and notifies the Homepage repository to sync via repository_dispatch (event type showcase-updated).
Template Repository Release Pipeline
Unified Pattern Across Three Language Starters
The three Starter repositories (Go / Rust / TypeScript) share the same release pattern:
- Triggered by pushing tag
v* - Build 6-platform binaries (3 OS x 2 architectures)
- Generate
SHA256SUMSchecksum file - Create GitHub Release via
softprops/action-gh-release
The template name is read from the name field in manifest.json; artifact naming format: presto-template-{name}-{os}-{arch}.
Build Differences
| Starter | Language | Build Method | Cross-Compilation Approach |
|---|---|---|---|
| Go | Go | go build -trimpath | GOOS/GOARCH environment variables |
| Rust | Rust | cargo build --release | cross (Linux arm64, Windows arm64) |
| TypeScript | Bun | bun build --compile | --target specifies platform |
Go Starter cross-compiles everything on ubuntu-latest (CGO_ENABLED=0). Rust Starter uses native Runners for macOS, and cross containerized cross-compilation for Linux/Windows arm64. TypeScript Starter uses Bun's --compile --target to compile into standalone binaries, building macOS on macos-latest and the rest on ubuntu-latest.
presto-official-templates Smart Incremental Build
The official templates repository (monorepo) release.yml includes incremental detection logic:
changesJob compares file changes between the current tag and the previous tag- Only templates in changed directories enter the build matrix
- Shared files (
go.mod,.github/,internal/) changes trigger a full rebuild - Falls back to full build on first release or when detection is not possible
Build matrix: {template} x {darwin,linux,windows} x {amd64,arm64}, all using CGO_ENABLED=0 cross-compilation, no native Runners needed.
Security Testing
All template Starters and official templates run security checks via make test, verifying that binaries don't contain prohibited imports (net, os/exec, plugin, etc.). These tests run during local development; CI does not have a separate security scanning workflow.
Registry CI
The template registry (template-registry) CI pipeline includes three workflows using a dual-job security isolation architecture. See Registry Architecture for details.
Homepage Sync Mechanism
sync-release.yml
Triggered by the last step of Presto repository's release.yml via repository_dispatch (event type release-published).
Workflow:
- Fetch Release metadata and asset files from the Presto repository
- Create a same-named Release in the Homepage repository (mirror distribution)
- Update version numbers in source code (
Download.astro,Hero.astro) - Auto-commit and push version changes
sync-showcase.yml
Triggered by Presto repository's build-showcase.yml via repository_dispatch (event type showcase-updated).
Workflow:
- Clean old files (
rm -rf public/_app public/showcase) - Download
showcase-staticartifact from Presto repository usingdawidd6/action-download-artifact - Auto-commit and push to Homepage repository
Both sync workflows support manual triggering via workflow_dispatch.
Workflow Quick Reference
Presto (Main App)
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Release | release.yml | tag v* | DMG / ZIP / tar.gz / Docker image |
| Build Showcase | build-showcase.yml | push main | showcase-static artifact |
| Security Scan | security-scan.yml | cron / PR / manual | Scan reports |
presto-official-templates
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Release | release.yml | tag v* | Incremental template binaries + SHA256SUMS |
presto-template-starter-go
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Release | release.yml | tag v* | 6-platform binaries + SHA256SUMS |
presto-template-starter-rust
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Release | release.yml | tag v* | 6-platform binaries + SHA256SUMS |
presto-template-starter-typescript
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Release | release.yml | tag v* | 6-platform binaries + SHA256SUMS |
template-registry
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Update Registry | update-registry.yml | daily cron / manual | registry.json + SVG previews |
| Check Versions | check-versions.yml | daily cron / manual | Automated PR |
| Build Verified | build-verified.yml | push main | Verified template build artifacts |
Presto-homepage
| Workflow | File | Trigger | Artifacts |
|---|---|---|---|
| Sync Release | sync-release.yml | dispatch / manual | Mirror Release + version update |
| Sync Showcase | sync-showcase.yml | dispatch / manual | Static file sync |
Common Patterns
Pinning Action Versions by Commit SHA
All third-party Actions in workflows are referenced by full commit SHA instead of tag references, preventing supply chain attacks. Example:
# Correct: SHA pinned
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
# Avoid: tag reference (can be tampered with)
# - uses: actions/checkout@v4SHA256 Verification
All externally downloaded binaries are verified with SHA256 checksums:
- Typst CLI: Inline
typst_sha256field in the CI matrix - llvm-mingw toolchain: Hardcoded
EXPECTED_HASHverified withsha256sum -c - Release artifacts:
sha256sumgenerateschecksums.txtorSHA256SUMS
softprops/action-gh-release
Template repositories (Starters + official templates) uniformly use softprops/action-gh-release (SHA pinned) to create GitHub Releases, with generate_release_notes: true for automatic changelog generation.
The Presto main app uses the gh release create CLI command, supporting prerelease marking (-rc, -beta, -alpha suffixes auto-detected).
No goreleaser
The Presto organization does not use goreleaser. Build logic is managed directly through Makefile + GitHub Actions matrix, maintaining full control over the build process.
