Files
paste 8bef637053
CI / build-and-smoke (push) Failing after 31s
update readme
2026-06-25 21:56:39 -05:00

119 lines
5.1 KiB
Markdown

# mpq-packager
A CI packager for World of Warcraft **MPQ patch archives** — the MPQ equivalent
of [BigWigsMods/packager](https://github.com/BigWigsMods/packager). Point it at a
WoW interface repo and it produces a vanilla-1.12-compatible `patch-X.mpq`,
ready to attach to a Gitea release.
It runs as a **Gitea Action** on a Linux runner. MPQs are built with
[StormLib](https://github.com/ladislav-zezula/StormLib) (the MoPaQ library
Ladik's MPQ Editor is itself built on) so no Windows host or Wine is needed.
## What it does
1. Reads a manifest (`mpq.yaml`) describing what to pack and where it lands
inside the archive.
2. Stages the selected files, honouring ignore globs.
3. Optionally substitutes `@project-version@` / `@project-revision@` /
`@project-date-iso@` tokens in text files.
4. Names the output `patch-<letter>.mpq` — vanilla 1.12's loader only accepts a
**single-character** suffix (`patch-Z.mpq` ✅, `patch-myproject.mpq` ❌).
5. Builds the archive as **MPQ format v1** with zlib-compressed sectors and a
`(listfile)`.
## Usage in a consuming repo
Add a manifest at the repo root (`mpq.yaml`):
```yaml
name: GlueXML
patch-letter: Z # high letters sort last → win on conflict
substitute:
enabled: true
extensions: [".lua", ".xml", ".toc"]
contents:
- src: . # repo root
dest: Interface/GlueXML # in-MPQ path (slashes become backslashes)
ignore:
- ".git/**"
- ".gitea/**"
- "mpq.yaml"
- "*.md"
```
Add a release workflow at `.gitea/workflows/release.yml` (see
[`examples/release.yml`](examples/release.yml)). Pushing a tag like `v1.0.0`
builds the MPQ and attaches it to a matching Gitea release:
```yaml
- uses: paste/mpq-packager@v1
id: pack
with:
manifest: mpq.yaml
version: ${{ github.ref_name }}
# steps.pack.outputs.mpq-path / mpq-name point at the built archive
```
Working examples for the GlueXML repo live in [`examples/`](examples/).
## Manifest reference
| Key | Default | Meaning |
|-----------------|--------------------|----------------------------------------------------------------|
| `name` | — | Cosmetic, used in logs. |
| `patch-letter` | `Z` | Single char; becomes `patch-<letter>.mpq`. |
| `max-files` | file count + 16 | Hash-table sizing hint (StormLib rounds up to a power of two). |
| `substitute` | disabled | `enabled` + `extensions` list for `@token@` replacement. |
| `contents[].src` | `.` | Repo-relative file or directory to pack. |
| `contents[].dest` | — | In-MPQ destination path (forward slashes; converted to `\`). |
| `contents[].ignore` | `[]` | Glob patterns matched against repo-relative paths. |
## Action inputs / outputs
| Input | Default | Description |
|------------|------------|----------------------------------------------------------|
| `manifest` | `mpq.yaml` | Manifest path, relative to repo root. |
| `version` | ref name | Stamped into `@project-version@`. |
| `out-dir` | `dist` | Where the `.mpq` is written. |
| Output | Description |
|------------|--------------------------------------|
| `mpq-path` | Filesystem path of the built `.mpq`. |
| `mpq-name` | Filename, e.g. `patch-Z.mpq`. |
## Prerequisites
- **Actions enabled** on the consuming repo (repo Settings → Actions).
- An **`act_runner`** registered to your Gitea instance advertising a label your
workflow's `runs-on` uses (e.g. `ubuntu-latest`), with Docker available.
## Local build & test
```bash
docker build -t mpq-packager .
docker run --rm \
-e INPUT_MANIFEST=mpq.yaml -e INPUT_VERSION=v0.0.0 \
-e INPUT_OUT_DIR=/work/dist -e GITHUB_WORKSPACE=/work \
-v "$PWD/test:/work" mpq-packager
# -> test/dist/patch-Z.mpq
```
## Layout
| Path | Role |
|---------------------|-----------------------------------------------------------|
| `src/mpqpack.c` | StormLib-based packer: staging dir → MPQ v1. |
| `package.py` | Orchestration: manifest, staging, ignores, substitution. |
| `entrypoint.sh` | Action entrypoint wiring `INPUT_*` env to `package.py`. |
| `Dockerfile` | Builds StormLib + `mpqpack`; ships the runtime image. |
| `action.yml` | Gitea/GitHub Docker action definition. |
| `examples/` | Manifest + release workflow for a consuming repo. |
| `test/` | Fixture + manifest exercised by CI. |
## Notes & caveats
- **`Blizzard_*` addons** still go through the engine's `.toc.sig` check
regardless of MPQ residency — packaging them here does not bypass it.
- Compression is zlib, which vanilla 1.12.1 decompresses. The output is MPQ v1
specifically; v2+ headers are not read by the 1.12 loader.