Builds & Artifacts
Building from source and uploading compiled binaries as artifacts.
An artifact is a compiled binary or bundle stored in zectre-registry. A build takes source (tarball or git ref) and produces an artifact. Once you have an artifact UUID, reference it when creating a deployment.
There are two paths:
| Path | When to use |
|---|---|
| Upload a binary | You compiled locally and want to push the binary directly |
| Build from source | You want the platform to compile from a project tarball |
| Git-triggered build | You have source config set and want one-command deploy |
Upload a binary
POST /api/v1/artifacts — Create record
Creates the artifact metadata entry. The binary is uploaded separately.
Body
- name (string): Human-readable name
- content_type (string): e.g.
"application/octet-stream"
ARTIFACT_ID=$(curl -sf -X POST http://localhost:47080/api/v1/artifacts \
-H 'Content-Type: application/json' \
-d '{"name":"my-app-v1.0","content_type":"application/octet-stream"}' \
| jq -r .id)POST /api/v1/artifacts//upload — Upload binary
Body is raw bytes. Proxied to zectre-registry.
curl -X POST http://localhost:47080/api/v1/artifacts/$ARTIFACT_ID/upload \
-H 'Content-Type: application/octet-stream' \
--data-binary @./my-appGET /api/v1/artifacts//download
Download the artifact bytes. Also proxied to zectre-registry.
GET /api/v1/artifacts/
Fetch artifact metadata (name, content type, size, SHA-256).
GET /api/v1/artifacts
List all artifacts.
Full upload example
# 1. Create record
ARTIFACT_ID=$(curl -sf -X POST http://localhost:47080/api/v1/artifacts \
-H 'Content-Type: application/json' \
-d '{"name":"my-app-v1.0","content_type":"application/octet-stream"}' \
| jq -r .id)
# 2. Upload binary
curl -X POST http://localhost:47080/api/v1/artifacts/$ARTIFACT_ID/upload \
-H 'Content-Type: application/octet-stream' \
--data-binary @./target/release/my-app
# 3. Deploy
curl -X POST http://localhost:47080/api/v1/apps/$APP_ID/deployments \
-H 'Content-Type: application/json' \
-d "{\"artifact_id\":\"$ARTIFACT_ID\",\"process_type\":\"tish\",\"replicas\":1}"Build from source
POST /api/v1/builds — Submit
Accepts a multipart body (100MB limit) with two fields:
| Field | Type | Content |
|---|---|---|
metadata | JSON text | {"app_id":"uuid","features":["full"]} |
project | file | Gzipped tarball of the project |
# Pack the project (exclude build outputs)
tar czf /tmp/project.tar.gz --exclude='.git' --exclude='target' .
# Submit
BUILD=$(curl -sf -X POST http://localhost:47080/api/v1/builds \
-F 'metadata={"app_id":"'$APP_ID'","features":["full"]}' \
-F 'project=@/tmp/project.tar.gz')
BUILD_ID=$(echo $BUILD | jq -r .id)Metadata fields
- app_id (UUID): The app this build is for
- features (array, optional): Feature flags for the build (e.g.
["full"],["http","process"]) - deployment_id (UUID, optional): If set, build logs are attached to this deployment and the deployment is updated on completion
GET /api/v1/builds/ — Poll status
while true; do
BUILD=$(curl -sf http://localhost:47080/api/v1/builds/$BUILD_ID)
STATUS=$(echo $BUILD | jq -r .status)
STAGE=$(echo $BUILD | jq -r '.stage // ""')
echo "Build $STATUS — $STAGE"
[ "$STATUS" = "succeeded" ] || [ "$STATUS" = "failed" ] && break
sleep 5
done
ARTIFACT_ID=$(echo $BUILD | jq -r .artifact_id)Response fields
- status:
pending|running|succeeded|failed - progress: 0–100
- stage: Current build stage (e.g.
"compiling","done") - artifact_id: UUID of the produced artifact (populated on success)
- error: Error message (populated on failure)
Full build + deploy example
import time, requests
BASE = "http://localhost:47080"
def build_and_deploy(app_id, tarball_path):
# 1. Submit build
with open(tarball_path, "rb") as f:
r = requests.post(f"{BASE}/api/v1/builds", files={
"metadata": (None, f'{{"app_id":"{app_id}","features":["full"]}}'),
"project": ("project.tar.gz", f, "application/gzip"),
})
build_id = r.json()["id"]
print(f"Build started: {build_id}")
# 2. Poll
while True:
build = requests.get(f"{BASE}/api/v1/builds/{build_id}").json()
print(f" {build['status']} — {build.get('stage','')}")
if build["status"] == "succeeded":
break
if build["status"] == "failed":
raise RuntimeError(f"Build failed: {build.get('error')}")
time.sleep(5)
artifact_id = build["artifact_id"]
# 3. Deploy
r = requests.post(f"{BASE}/api/v1/apps/{app_id}/deployments", json={
"artifact_id": artifact_id,
"process_type": "tish",
"replicas": 1,
})
d = r.json()
print(f"Deployed: {d['id']} — preview: {d.get('preview_url')}")
return dGit-triggered build (deploy/trigger)
If you have source config set up, one call handles build + deploy. See POST /api/v1/apps//deploy/trigger in the Deployments page.
See also
- Deployments — creating and managing deployments
- Applications — source config for git-triggered builds
- Internal services —
zectre-buildandzectre-registrydetails