Flight builds your repository the way you would build it locally, so most repositories need exactly one new file. This page is what goes in it, plus the handful of things about the build machine that change how you write your Makefile.
What your repository needs#
- your-repothe repository root
- .ceagle-flightrequired, at the root
- makefileor whatever your build command runs
- src
- main.c
- bincreated by the build, gitignored
Only .ceagle-flight is new. Everything else is however your project already builds.
The minimum manifest#
[program]
name = "Snake"
version = "1.0.0"
[build]
output = "bin/SNAKE.8xp"That builds. Everything else has a default: the command defaults to make, the timeout to ten
minutes, the categories to other, and submodules are off.
A realistic manifest#
[program]
name = "Snake"
version = "1.2.0"
summary = "The classic, on your calculator."
description = """
Eat the pixels. Do not eat yourself.
Hold [2nd] to sprint.
"""
categories = ["games"]
tags = ["arcade", "classic"]
author = "Ada Lovelace"
depends = ["graphx-helpers"]
[build]
command = "make"
output = "bin/SNAKE.8xp"
submodules = false
timeout = "10m"Every key, its default, its limit, and the error you get when it is wrong.
Getting the output path right#
output is the one field that fails most first builds. It is a path relative to the repository
root, and it has to match exactly one regular file after the build finishes.
Find what your Makefile is called
The CE C toolchain's standard makefile writes into
bin/, named after theNAMEvariable:makefileNAME = SNAKE ICON = icon.png DESCRIPTION = "Snake" COMPRESSED = NO include $(shell cedev-config --makefile)With
NAME = SNAKEthe artifact isbin/SNAKE.8xp.Write that path, or a glob that matches it
output = "bin/SNAKE.8xp"A glob is fine when you would rather not repeat the name:
output = "bin/*.8xp"Make sure only one file matches
A glob that matches two files fails with
the output pattern matched more than one file. That happens most often when a previous build left something inbin/, or when the repository ships a prebuilt binary. Addbin/to.gitignore.
relativeRequiredIt must stay inside the repository. Absolute paths, backslashes and any
..segment are rejected before the build runs.one matchRequiredZero matches and two matches are both failures, with different errors.
a regular fileRequiredA symlink is refused rather than followed, even if it points somewhere legitimate.
sizeat most 8 MiBAnd the variable body itself has to fit in a calculator variable.
Writing a Makefile that works here#
The build machine is not your machine. Four differences matter.
There is no network
The container runs with networking disabled. A Makefile that downloads a dependency, clones something, or runs a package manager fails.
Everything a build needs has to be in the repository, or a git submodule, or already in the image.
The toolchain is already installed
The CE C toolchain is at
/opt/CEdev,CEDEVis set, and/opt/CEdev/binis on thePATH. Do not try to install it.include $(shell cedev-config --makefile)works as-is.
Submodules are off by default
If your build needs them, say so:
[build] submodules = trueThey are cloned with the same protocol allow-list as the repository, so only HTTPS submodules resolve.
The command runs through a login shell
The build runs
bash -lcwith your command, in the directory holding your manifest, as an unprivileged user.CEAGLE_FLIGHT=1is set, so a Makefile can branch on it:ifdef CEAGLE_FLIGHT COMPRESSED = YES endif
The exact image, the toolchain version, the environment variables and the limits.
Connect it in the console#
Install the GitHub App
From the project's Flight tab. Grant it the repository. It asks to read metadata, and to write deployments and commit statuses so a build shows up on the commit.
Pick the repository and branch
Only public repositories are eligible. The branch defaults to the repository default.
Leave build on push enabled
A push to the tracked branch then starts a build on its own.
Test the manifest before you push#
There is no offline validator, but the console serves a known-good example for any language and mode, which is useful to diff against:
curl -s "https://roost.ceagle.cc/api/v1/manifest?language=asm"
curl -s "https://roost.ceagle.cc/api/v1/manifest?language=lib&mode=libify"
curl -s "https://roost.ceagle.cc/api/v1/manifest?language=lib&mode=custom"A repository that backs two projects#
A repository may back as many projects as it has manifests. Each project is connected with its own manifest path, and no two projects may name the same manifest in the same repository.
The usual shape is a monorepo holding a library and the application that uses it:
- your-repothe repository root
- libone project
- .ceagle-flight
- makefile
- appanother project
- .ceagle-flight
- makefile
- libone project
Create two projects, then connect each one to the same repository and give it its own path. The
path is the directory a project builds from, so lib and app here. Flight appends the manifest
name for you, and lib/.ceagle-flight means the same thing if you would rather be explicit.
Two manifests in one directory work too, when a single tree produces two artifacts from one build
system. Name the second one with a suffix, .ceagle-flight.app, and give that as the path.
The whole repository is checked out for every build, so a project in a subdirectory can still read
what sits beside it. A Makefile in app/ may include headers from ../lib. Only the paths the
manifest names are confined to the project's own directory.
Each project keeps its own address, its own listing, its own release history and its own build queue. A push to the tracked branch builds every project connected to that repository, not only the one whose files changed, because a change in a library is exactly when the application that links it needs rebuilding.
If what you have is a library and its consumer, consider publishing the library as a LibLoad library and declaring it as a dependency of the application. That works whether or not they share a repository.