Build Integration
stacy integrates with build systems through standard Unix exit codes. Any tool that stops on non-zero exit works with stacy.
Quick Examples
Make:
results.dta: analysis.do data.dta
stacy run analysis.do
Snakemake:
rule analysis:
input: "analysis.do", "data.dta"
output: "results.dta"
shell: "stacy run {input[0]}"
Shell:
stacy run step1.do && stacy run step2.do
GNU Make
Basic Makefile
STATA := stacy run
# Final output depends on analysis
results/tables.tex: src/03_tables.do results/estimates.dta
$(STATA) $<
# Estimates depend on clean data
results/estimates.dta: src/02_analysis.do data/clean.dta
$(STATA) $<
# Clean data depends on raw data
data/clean.dta: src/01_clean.do data/raw.dta
$(STATA) $<
.PHONY: all clean
all: results/tables.tex
clean:
rm -f data/clean.dta results/*.dta results/*.tex
With Package Installation
.PHONY: install
install:
stacy install
results.dta: analysis.do | install
stacy run $<
See GNU Make documentation for more patterns.
Snakemake
Basic Snakefile
rule all:
input: "results/tables.tex"
rule clean:
input: "src/01_clean.do", "data/raw.dta"
output: "data/clean.dta"
shell: "stacy run {input[0]}"
rule analysis:
input: "src/02_analysis.do", "data/clean.dta"
output: "results/estimates.dta"
shell: "stacy run {input[0]}"
rule tables:
input: "src/03_tables.do", "results/estimates.dta"
output: "results/tables.tex"
shell: "stacy run {input[0]}"
Parallel Execution
snakemake --cores 4
See Snakemake documentation for workflows, clusters, and more.
CI/CD
GitHub Actions
# .github/workflows/analysis.yml
name: Analysis
on: [push, pull_request]
jobs:
build:
runs-on: self-hosted # With Stata installed
steps:
- uses: actions/checkout@v4
- name: Install stacy
run: |
curl -fsSL https://raw.githubusercontent.com/janfasnacht/stacy/main/install.sh | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install packages
run: stacy install --frozen
- name: Run analysis
run: stacy run analysis.do
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: results
path: output/
Note:
--frozenfails if lockfile doesn’t match stacy.toml, catching uncommitted dependency changes.
GitLab CI
# .gitlab-ci.yml
analysis:
stage: build
before_script:
- curl -fsSL https://raw.githubusercontent.com/janfasnacht/stacy/main/install.sh | bash
- export PATH="$HOME/.local/bin:$PATH"
- stacy install
script:
- stacy run analysis.do
artifacts:
paths: [output/]
Caching Packages
- uses: actions/cache@v4
with:
path: ~/.cache/stacy/packages/
key: stata-packages-${{ hashFiles('stacy.lock') }}
Stata Licensing in CI
Stata requires a license. Options:
- Self-hosted runner with Stata installed
- Docker container with Stata
- Skip Stata steps in CI (validate config only)
See GitHub Actions docs or GitLab CI docs for more.
Best Practices
- Use
--frozenin CI to catch lockfile drift - Commit
stacy.lockfor reproducibility - Cache packages to speed up builds
- Use JSON output for programmatic checks:
stacy run --format json - Upload artifacts on failure for debugging
See Also
- How It Works - Exit codes and JSON
- Exit Codes - Code meanings