Compare commits
2 Commits
1662d550c7
..
v0.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 83248561cc | |||
| e522b4d6f5 |
@@ -0,0 +1,64 @@
|
||||
name: build
|
||||
|
||||
# Build a versioned Linux CLI release tarball (see `make package`) on
|
||||
# every push/PR, plus on-demand via the Gitea "Run workflow" button.
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# Runner defaults `run:` steps to `sh`, which doesn't understand
|
||||
# `set -o pipefail` used below — force bash explicitly.
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
# Must match a label your act_runner is registered with.
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# `make package`'s version comes from `git describe --tags` (see
|
||||
# the Makefile's `package` target) - needs full history/tags,
|
||||
# not actions/checkout's default shallow single-commit clone.
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Preflight
|
||||
run: |
|
||||
set -euo pipefail
|
||||
command -v cc >/dev/null 2>&1 || { echo "PREFLIGHT FAIL: no C compiler (cc) in PATH" >&2; exit 1; }
|
||||
command -v make >/dev/null 2>&1 || { echo "PREFLIGHT FAIL: make not in PATH" >&2; exit 1; }
|
||||
|
||||
- name: Build and test
|
||||
run: |
|
||||
set -euo pipefail
|
||||
make test
|
||||
make package
|
||||
|
||||
- name: Upload build artifact
|
||||
# v4 uses the newer @actions/artifact backend, which this Gitea
|
||||
# instance's artifact storage doesn't support (GHESNotSupportedError) — v3 works.
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: deck-in-a-dash
|
||||
path: dist/deck-in-a-dash-*-linux-*.tar.gz
|
||||
|
||||
- name: Publish to dl.ladkau.de
|
||||
# Uploads the tarball over SFTP instead of using
|
||||
# actions/upload-artifact (whose zip wrapping can't be disabled).
|
||||
# Only runs on push so PR builds don't publish.
|
||||
if: gitea.event_name == 'push'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
FILE="$(ls dist/deck-in-a-dash-*-linux-*.tar.gz)"
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.DL_SFTP_KEY }}" > ~/.ssh/dl_sftp_key
|
||||
chmod 600 ~/.ssh/dl_sftp_key
|
||||
sftp -i ~/.ssh/dl_sftp_key -P 2223 \
|
||||
-o StrictHostKeyChecking=accept-new \
|
||||
uploader@dl.ladkau.de <<EOF
|
||||
-mkdir files/deck-in-a-dash
|
||||
put $FILE files/deck-in-a-dash/$(basename "$FILE")
|
||||
EOF
|
||||
@@ -19,6 +19,7 @@ make # builds dist/{deck-engine,interpreter-cli}, dist/img/, dist/i18n/
|
||||
# dist/run-engine.sh, dist/run-interpreter.sh, dist/user.properties
|
||||
make test # builds and runs engine/tests/smoke_test.c and interpreter/tests/*_test.c
|
||||
make clean # removes build/ and the generated binaries/img/i18n (never touches dist/user.properties)
|
||||
make package # builds a versioned Linux CLI tarball at dist/ - see "Packaging" below
|
||||
```
|
||||
|
||||
A single `Makefile` at the repo root builds both `engine/` and
|
||||
@@ -63,6 +64,43 @@ Run a single smoke test by editing `engine/tests/smoke_test.c`'s `main()`
|
||||
temporarily, or just read its assertions — there's no test filter flag,
|
||||
the whole suite runs in milliseconds.
|
||||
|
||||
## Packaging
|
||||
|
||||
`make package` (a `Makefile` target, not a separate script) builds a
|
||||
fresh `all` and bundles it into a versioned, self-contained Linux CLI
|
||||
tarball at `dist/deck-in-a-dash-<version>-linux-<arch>.tar.gz` -
|
||||
`deck-engine`, `interpreter-cli`, `run-engine.sh`/`run-interpreter.sh`,
|
||||
`img/`, `i18n/`, `LICENSE`, `README.md`, `docs/reading.md` (renamed
|
||||
`READING.md`), and a placeholder `user.properties` (from
|
||||
`engine/scripts/user.properties.template`, **never**
|
||||
`dist/user.properties` itself - see below). Extracting the tarball
|
||||
anywhere and running the scripts/binaries from inside it works exactly
|
||||
like running them from `dist/` in place, since `run-engine.sh`/
|
||||
`run-interpreter.sh` already resolve every path relative to their own
|
||||
location (`SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"`), not the
|
||||
caller's working directory.
|
||||
|
||||
**Version**: defaults to the current commit's git tag, matching
|
||||
`vX.Y.Z` (the `v` is stripped); if `HEAD` isn't exactly on such a tag,
|
||||
it falls back to a `0.0.0-dev+<short-sha>` placeholder with a warning on
|
||||
stderr. Override either with `make package VERSION=1.2.3`. Push a
|
||||
`vX.Y.Z` tag to drive a real release version.
|
||||
|
||||
**Never packages `dist/user.properties`**: the staging step copies
|
||||
files into the package by explicit name only - never a wildcard or
|
||||
recursive copy of `dist/` itself - specifically so a filled-in
|
||||
`dist/user.properties` (real birth data, gitignored, private) can never
|
||||
end up in a distributable package. The package always gets the
|
||||
placeholder template instead, identical to what a first-time `make`
|
||||
seeds `dist/user.properties` with.
|
||||
|
||||
**CI** (`.gitea/workflows/build.yml`): runs `make test && make package`
|
||||
on every push/PR (plus manual dispatch). The resulting tarball is both
|
||||
kept as a Gitea Actions run artifact and, on `push` only (not PRs),
|
||||
published over SFTP to `dl.ladkau.de` under `files/deck-in-a-dash/` -
|
||||
requires a `DL_SFTP_KEY` secret configured on this repo (or inherited
|
||||
from the org/instance level).
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
@@ -91,8 +129,10 @@ deck_in_a_dash/
|
||||
tests/smoke_test.c
|
||||
scripts/run-engine.sh, scripts/run-interpreter.sh, scripts/user.properties.template
|
||||
interpreter/ Separate module + binary; see "Interpretation" below.
|
||||
dist/ Build output (gitignored-style; see Build & run).
|
||||
Makefile Single root Makefile, builds both engine/ and interpreter/.
|
||||
dist/ Build output (gitignored-style; see Build & run) and,
|
||||
after `make package`, versioned release tarballs.
|
||||
Makefile Single root Makefile, builds both engine/ and
|
||||
interpreter/, and packages a release (see Packaging).
|
||||
```
|
||||
|
||||
### Data flow / the real API
|
||||
|
||||
@@ -76,7 +76,11 @@ JSON_TEST_BIN := $(BUILD_DIR)/json_test
|
||||
NARRATIVE_TEST_BIN := $(BUILD_DIR)/narrative_test
|
||||
GUIDANCE_TEST_BIN := $(BUILD_DIR)/guidance_test
|
||||
|
||||
.PHONY: all test clean images i18n scripts
|
||||
# Linux CLI release tarball - see the `package` target below.
|
||||
ARCH := $(shell uname -m)
|
||||
PACKAGE_DIR := $(BUILD_DIR)/package
|
||||
|
||||
.PHONY: all test clean images i18n scripts package
|
||||
|
||||
all: $(ENGINE_BINARY) $(INTERP_BINARY) images i18n scripts
|
||||
|
||||
@@ -152,6 +156,47 @@ $(OBJ_DIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
# Builds a versioned Linux CLI release tarball at
|
||||
# dist/deck-in-a-dash-<version>-linux-<arch>.tar.gz. Version defaults to
|
||||
# the current git tag (vX.Y.Z, tag prefix stripped) - push a tag to drive
|
||||
# a release. Override with `make package VERSION=1.2.3`, or just run it
|
||||
# untagged for a local dev build (gets a 0.0.0-dev+<sha> placeholder
|
||||
# version, with a warning).
|
||||
#
|
||||
# Copies files into the staging dir by explicit name only - never a
|
||||
# wildcard/recursive copy of dist/ itself - so a real, filled-in
|
||||
# dist/user.properties (birth data, gitignored, private) can never
|
||||
# accidentally end up in a package. The package gets the placeholder
|
||||
# template instead, same as a first-time `make` produces.
|
||||
package: all
|
||||
@V="$(VERSION)"; \
|
||||
if [ -z "$$V" ]; then \
|
||||
if TAG=$$(git describe --tags --exact-match --match 'v[0-9]*.[0-9]*.[0-9]*' 2>/dev/null); then \
|
||||
V=$${TAG#v}; \
|
||||
else \
|
||||
V="0.0.0-dev+$$(git rev-parse --short HEAD)"; \
|
||||
echo "WARNING: HEAD is not on a vX.Y.Z tag - building placeholder version $$V (push a tag to drive a real release version)" >&2; \
|
||||
fi; \
|
||||
fi; \
|
||||
case "$$V" in \
|
||||
[0-9]*.[0-9]*.[0-9]*) ;; \
|
||||
*) echo "PREFLIGHT FAIL: VERSION '$$V' is not a semantic version (expected X.Y.Z, optionally with a -pre+meta suffix)" >&2; exit 1;; \
|
||||
esac; \
|
||||
PKG_NAME="deck-in-a-dash-$$V-linux-$(ARCH)"; \
|
||||
PKG_STAGE="$(PACKAGE_DIR)/$$PKG_NAME"; \
|
||||
echo "Packaging $$PKG_NAME"; \
|
||||
rm -rf "$$PKG_STAGE"; \
|
||||
mkdir -p "$$PKG_STAGE"; \
|
||||
cp $(ENGINE_BINARY) $(INTERP_BINARY) "$$PKG_STAGE/"; \
|
||||
cp $(DIST_DIR)/run-engine.sh $(DIST_DIR)/run-interpreter.sh "$$PKG_STAGE/"; \
|
||||
cp -r $(DIST_IMG_DIR) $(DIST_I18N_DIR) "$$PKG_STAGE/"; \
|
||||
cp $(ENGINE_SCRIPTS_DIR)/user.properties.template "$$PKG_STAGE/user.properties"; \
|
||||
cp LICENSE README.md "$$PKG_STAGE/"; \
|
||||
cp docs/reading.md "$$PKG_STAGE/READING.md"; \
|
||||
tar -czf "$(DIST_DIR)/$$PKG_NAME.tar.gz" -C "$(PACKAGE_DIR)" "$$PKG_NAME"; \
|
||||
rm -rf "$(PACKAGE_DIR)"; \
|
||||
echo "Wrote $(DIST_DIR)/$$PKG_NAME.tar.gz"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(ENGINE_BINARY) $(INTERP_BINARY) $(DIST_IMG_DIR) $(DIST_I18N_DIR) \
|
||||
$(DIST_DIR)/run-engine.sh $(DIST_DIR)/run-interpreter.sh
|
||||
|
||||
@@ -53,7 +53,8 @@ interpreter/ Separate module + binary (dist/interpreter-cli)
|
||||
--format text|html|json and --lang en|de for
|
||||
its own output too (see CLAUDE.md).
|
||||
docs/ Architecture/dataflow diagrams, input/output format reference.
|
||||
Makefile Single root Makefile, builds both engine/ and interpreter/.
|
||||
Makefile Single root Makefile, builds both engine/ and
|
||||
interpreter/, and packages a release (`make package`).
|
||||
```
|
||||
|
||||
See [`CLAUDE.md`](CLAUDE.md) for the detailed architecture and the sharp
|
||||
@@ -69,6 +70,10 @@ struct format reference
|
||||
make # -> dist/deck-engine, dist/interpreter-cli, dist/img/, dist/i18n/,
|
||||
# dist/run-engine.sh, dist/run-interpreter.sh, dist/user.properties
|
||||
make test # builds and runs engine/tests/smoke_test.c and interpreter/tests/*_test.c
|
||||
make package # -> dist/deck-in-a-dash-<version>-linux-<arch>.tar.gz, a
|
||||
# self-contained release bundle (binaries, scripts, img/, i18n/,
|
||||
# LICENSE, docs) - version from the current git tag, or
|
||||
# VERSION=1.2.3 make package to override
|
||||
```
|
||||
|
||||
Requires only a C99 compiler and `make` — no other dependencies.
|
||||
|
||||
Reference in New Issue
Block a user