.. _howto-first-build: Your first build ================ Goal: submit a build, watch the logs, get the artifacts back. Before you start ---------------- Two things: - An account. :doc:`login` signs the CLI in with your Gitea or GitHub account, so the build lands in a project of yours. - A runner. saggar.dev builds nothing itself; a job with no eligible runner stays queued. :doc:`runners` pairs a machine in a few minutes. 1. Submit --------- Point ``saggar submit`` at any source: a git URL or a local tree. .. code-block:: console $ saggar submit https://github.com/me/my-project $ saggar submit ./my-project # a directory with a Dockerfile $ saggar submit ./my-project.tar.gz # or a tarball What the tree is decides what gets built, with no build script required: - A ``.debian/`` or ``debian/`` directory builds a ``.deb`` (the changelog's series decides the environment). - A ``Dockerfile`` builds an image. - ``snapcraft.yaml`` builds a snap, a flatpak manifest a flatpak bundle, a root ``*.spec`` rpms, ``appimagebuilder.yml`` an AppImage. - ``CMakeLists.txt``, ``meson.build``, ``Cargo.toml``, ``go.mod``, ``Makefile`` and friends get a native build. It answers whether the tree compiles; what the build produces is collected, and a green compile with nothing to collect is a build-check success. The CLI follows the build: live log in the terminal, then the verdict. Overrides for this push: ``--format deb`` (skip detection), ``--arch arm64`` or ``--env "debian:12 + rust"`` (target override), ``--project web`` (which of your projects owns the build). 2. Follow the logs ------------------ The follow loop already streams the log. For an existing job, the full log is one command: .. code-block:: console $ saggar logs j-567bf3b889d9bb70 If you submitted with ``--no-wait`` (or you are scripting and passed ``--quiet``, which prints only the id), poll the job and stream in your browser or via the SSE endpoint (see :doc:`../reference/api`). When a build fails, the failure is classified: ``real`` is a genuine defect in your code or packaging; ``infra-retryable`` is environment noise (retried silently, you never see it); ``infra-permanent`` is a fault no retry fixes. ``saggar logs`` and the API's failure metadata tell you which. 3. Download the artifacts ------------------------- .. code-block:: console $ saggar download j-567bf3b889d9bb70 --extract -o out/ Job downloads default to this machine's arch; ``--arch riscv64`` fetches another target, and arch-independent (``all``) artifacts always come along. ``--extract`` unpacks tarballs preserving executable bits. For a fan-out group, everything at once: .. code-block:: console $ saggar download --group g-1a2b3c4d -o out/ Next steps ---------- - Keep the store clean while iterating: ``--ephemeral``, or run the tests instead of building: :doc:`test-mode`. - Turn one submission into many: :doc:`fan-out`. - Consume artifacts straight from the registries: :doc:`publish-consume`.