Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 14 additions & 22 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,21 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v5

- name: Copy packages.dhall to the root
run: cp ./src/packages.dhall packages.dhall
- uses: cachix/install-nix-action@v31

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: false
# Consumable asset: a full RemotePackageSet (registry baseline + Lua fork
# git overrides) for the new spago via `workspace.packageSet.url`.
- name: Generate packages.json
run: ./scripts/gen-package-set-json

- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./packages.dhall
asset_name: packages.dhall
asset_content_type: application/x-dhall
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--title "$GITHUB_REF_NAME" \
--notes "PureScript Lua package set \`$GITHUB_REF_NAME\` for the new spago: point \`workspace.packageSet.url\` at this release's \`packages.json\`." \
./packages.json
30 changes: 17 additions & 13 deletions .github/workflows/test-set.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: Test set

# Coherence check for the whole set. Builds a project that depends on every
# package (test/spago.dhall) against `upstream-ps // ./src/packages.dhall`,
# using a SINGLE current toolchain (purs + spago from the pslua compiler's
# dev shell). A red run means the pinned package versions do not compile
# together.
# Coherence check for the whole set. Generates the consumable package set
# (packages.json) with scripts/gen-package-set-json, then builds a project that
# depends on every Lua fork (test/spago.yaml) against it, using a SINGLE current
# toolchain (purs + spago from the pslua compiler's dev shell). A red run means
# the pinned package versions do not compile together — or the generator
# produced a set spago cannot consume.
#
# This deliberately does NOT enter each package's own flake: that rebuilt the
# compiler revision frozen in every tag's flake.lock (cache-miss roulette on
Expand Down Expand Up @@ -32,31 +33,34 @@ jobs:
- name: Free up disk space
uses: wimpysworld/nothing-but-nix@687c797a730352432950c707ab493fcc951818d7

- uses: actions/checkout@v4
- uses: actions/checkout@v5

- uses: cachix/install-nix-action@v27
- uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
extra-substituters = https://cache.iog.io https://purescript-lua.cachix.org
extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= purescript-lua.cachix.org-1:yLs4ei2HtnuPtzLekOrW3xdfm95+Etw15gwgyIGTayA=

- uses: cachix/cachix-action@v14
- uses: cachix/cachix-action@v17
with:
name: purescript-lua

- name: Generate the consumable package set (packages.json)
run: ./scripts/gen-package-set-json

- name: Build the whole set with one toolchain
run: |
nix develop github:purescript-lua/purescript-lua --accept-flake-config \
-c bash -c 'cd test && spago build -u "-g corefn"'
-c bash -c 'cd test && spago build'

# The README package table is generated from src/packages.dhall; guard against
# The README package table is generated from src/packages.json; guard against
# hand-edits / forgotten regeneration so it cannot drift out of sync again.
readme-table:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
- name: README package table is in sync with src/packages.dhall
- uses: actions/checkout@v5
- uses: cachix/install-nix-action@v31
- name: README package table is in sync with src/packages.json
run: ./scripts/gen-readme-table.sh --check
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Release artifact assembled from src/packages.json at release time
# (scripts/gen-package-set-json / the release workflow). The single source of
# truth is src/packages.json; this is generated, never committed.
/packages.json

# Local-only working files (drafts, notes); never pushed.
/.local/
23 changes: 16 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ rule lives in [`docs/adr/`](docs/adr/).

## Toolchain

Pinned through purescript-overlay ([ADR 0001](docs/adr/0001-overlay-flake-toolchain.md)):
purs 0.15.16, spago 0.21.0, Lua 5.1. Enter the dev shell with `nix develop`. Keep
`flake.lock` reasonably current with `nix flake update`; a long-stale pslua pin
breaks the build.
Pinned through purescript-overlay ([ADR 0001](docs/adr/0001-overlay-flake-toolchain.md),
[ADR 0008](docs/adr/0008-new-spago-and-json-package-set.md)): purs 0.15.16, spago
1.x (the new PureScript spago — `spago.yaml`/`spago.lock`, not `spago.dhall`), Lua
5.1. Each fork carries its own `flake.nix`: enter its dev shell with `nix develop`
and keep `flake.lock` reasonably current with `nix flake update` (a long-stale
pslua pin breaks the build). This set repository has no flake of its own; its CI
builds through the pslua dev shell (`nix develop github:purescript-lua/purescript-lua`).

## Commands

Expand Down Expand Up @@ -40,13 +43,19 @@ imports it with `@AGENTS.md`. Edit `AGENTS.md`; never duplicate.

## Releasing ([ADR 0006](docs/adr/0006-fork-release-by-annotated-tag.md))

Annotated git tag on `master` → bump the fork's version in `src/packages.dhall` →
Annotated git tag on `master` → bump the fork's version in `src/packages.json` →
regenerate the README package table (`scripts/gen-readme-table.sh`) →
refresh `latest-compatible-sets.json` → push a `psc-*` set tag. A tooling-only PR
needs no release.

The README package table is generated from `src/packages.dhall` (the single
source of truth) — run `scripts/gen-readme-table.sh` after any version bump and
A `psc-*` tag publishes one release asset
([ADR 0008](docs/adr/0008-new-spago-and-json-package-set.md)): `packages.json`,
the consumable RemotePackageSet for the new spago (`workspace.packageSet.url`),
built from `src/packages.json` by `scripts/gen-package-set-json`. spago 0.21 /
Dhall is no longer supported.

The README package table is generated from `src/packages.json` (the single
source of truth): run `scripts/gen-readme-table.sh` after any version bump and
commit the result. CI (`scripts/gen-readme-table.sh --check`) fails if it drifts.

## Decisions and ADRs
Expand Down
45 changes: 20 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,38 @@ the PureScript-to-Lua compiler backend. It collects the core PureScript
libraries as Lua forks: each fork keeps the upstream PureScript sources and
replaces the JavaScript FFI with Lua that runs on Lua 5.1.

[`src/packages.dhall`](src/packages.dhall) holds only these Lua forks. It is the
*overrides* half of a set, not a whole set: the release workflow copies it
verbatim into each `psc-*` release asset. To build a project you merge it with
the standard PureScript set and let the Lua forks win over their
JavaScript-targeting upstreams.
[`src/packages.json`](src/packages.json) is the source of truth: it lists only
the Lua forks. Each `psc-*` release folds it onto a pinned upstream PureScript
registry set and publishes the result as `packages.json`, a complete set you
consume directly with the new spago.

## Using the set with spago

In your project's `packages.dhall`, import both the upstream PureScript set and a
released Lua set, then merge them so the Lua forks override the upstreams:
Point `workspace.packageSet.url` at a released `packages.json`:

```dhall
let upstream-ps =
https://github.com/purescript/package-sets/releases/download/psc-0.15.15-20240309/packages.dhall

let upstream-lua =
https://github.com/purescript-lua/purescript-lua-package-sets/releases/download/psc-0.15.15-20260615/packages.dhall

in upstream-ps // upstream-lua
```yaml
workspace:
packageSet:
url: https://github.com/purescript-lua/purescript-lua-package-sets/releases/download/psc-0.15.15-20260624/packages.json
```

The right operand wins, so every package that has a Lua fork comes from this set
and everything else comes straight from the PureScript set. Pointing `upstream`
at the Lua release on its own would give you only the forks, which is why the
merge is required.

Lua releases are tagged `psc-0.15.15-<YYYYMMDD>[-N]`;
That set already carries the Lua forks in place of their JavaScript-targeting
upstreams, so you just list what you need under `package.dependencies`: no
`extraPackages` block and no merge. Releases are tagged
`psc-0.15.15-<YYYYMMDD>[-N]`;
[`latest-compatible-sets.json`](latest-compatible-sets.json) records the most
recent one, and `spago upgrade-set --tag <tag>` moves between them.
recent one.

The set targets the new spago (`spago.yaml`/`spago.lock`). spago 0.21 / Dhall is
no longer supported.

## Packages

The Lua forks in this set. Each keeps its upstream PureScript API and ships a Lua
FFI in place of the JavaScript one. The package name is the Dhall key in
`src/packages.dhall` — note that the OpenResty bindings are keyed `lua-ngx`.
FFI in place of the JavaScript one. The package name is the key in
`src/packages.json`; note that the OpenResty bindings are keyed `lua-ngx`.

<!-- BEGIN PACKAGE TABLE (generated by scripts/gen-readme-table.sh from src/packages.dhall — do not edit by hand) -->
<!-- BEGIN PACKAGE TABLE (generated by scripts/gen-readme-table.sh from src/packages.json — do not edit by hand) -->
| Package | Repository | Version |
|---|---|---|
| arrays | https://github.com/purescript-lua/purescript-lua-arrays | v7.4.1 |
Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0001-overlay-flake-toolchain.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 0001 — Pin the toolchain with purescript-overlay

Status: Accepted
Status: Accepted (spago pin superseded by [0008](0008-new-spago-and-json-package-set.md): spago 0.21.0 → 1.x; the purs 0.15.16 and Lua 5.1 pins stand)

## Context

Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0006-fork-release-by-annotated-tag.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tags with no GitHub Release attached.

A fork release is an annotated git tag on `master`, pushed to the fork. No GitHub
Release and no per-fork changelog entry. After tagging, bump the fork's `version`
in this repository's `src/packages.dhall`, refresh `latest-compatible-sets.json`,
in this repository's `src/packages.json`, refresh `latest-compatible-sets.json`,
and push a `psc-0.15.15-<YYYYMMDD>[-N]` set tag, which the release workflow turns
into the set asset. A pull request that touches only tooling, CI, or the flake
(not `src/`) needs no tag or set bump, because spago consumes `src/` only.
Expand Down
65 changes: 65 additions & 0 deletions docs/adr/0008-new-spago-and-json-package-set.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 0008 — Publish a consumable JSON package set for the new spago

Status: Accepted (supersedes the spago pin in [0001](0001-overlay-flake-toolchain.md))

## Context

The set was built for the legacy spago (0.21.0): a Dhall overlay
(`src/packages.dhall`) holding only the Lua forks, released as a `packages.dhall`
asset that a consumer merged with the upstream PureScript set
(`upstream-ps // upstream-lua`). The right operand won, so each fork overrode its
JavaScript-targeting upstream. ADR 0001 pinned spago 0.21.0 across the forks to
make this work.

The PureScript toolchain has moved to the new spago (1.x), which drives
`spago.yaml` + `spago.lock` and the PureScript Registry, and dropped Dhall. pslua
itself migrated its test toolchain to it (pslua #54, #55). The new spago has no
Dhall and no set-merge operator: `workspace.packageSet` takes a *single* source —
a registry version, a URL, or a path. So the old "merge two Dhall sets" model
cannot be expressed, and a forks-only overlay is no longer directly consumable.

A spike (pslua #115) confirmed three ways — the spago docs, the `core/src/Config.purs`
codecs (`RemotePackage = git | registry-version | legacy`), and a working PoC —
that the new spago consumes a *custom* set through `packageSet.url` / `packageSet.path`,
and that such a set may carry git-based package entries. So the set can become a
single, self-contained, consumable input again.

## Decision

Each release publishes a `packages.json` asset: a RemotePackageSet
(`{ compiler, version, packages }`) where the pure packages come from a pinned
upstream **registry package set** baseline (the proven-compatible 77.x set; see
the generator) and the Lua forks are overlaid as **git entries**
(`{ git, ref, dependencies }`). `src/packages.json` is the single source of truth
for the forks (a small overlay); `scripts/gen-package-set-json` reshapes it onto
the baseline. Consumers point `workspace.packageSet.url` at the published
`packages.json` and drop `extraPackages` entirely.

The forks and the set's own coherence check migrate to the new spago (1.x):
`spago.yaml` replaces `spago.dhall`/`packages.dhall`, and the toolchain pin moves
from `spago-bin.spago-0_21_0` to `spago-bin.spago-1_0_4`. This **supersedes the
spago 0.21.0 pin in ADR 0001**; the purs 0.15.16 and Lua 5.1 pins there stand.

Dhall is dropped wholesale: the overlay source becomes `src/packages.json`, the
legacy `packages.dhall` release asset is removed, and the `dhall-to-json` step
leaves the generator and the README-table script. spago 0.21 / Dhall consumers
are no longer supported — the whole ecosystem moves to the new spago.

## Consequences

- The set is a live build input again — one URL, no `//` merge, no inlined
`extraPackages` dependency lists in every consumer.
- `packages.json` is generated, never committed: `scripts/gen-package-set-json`
builds it from `src/packages.json` + the pinned registry baseline. The
coherence check (`test-set.yml`) regenerates it and builds against it, so the
generator is exercised on every push.
- The published `version`/`compiler` fields are the registry baseline's
(`0.15.15` / its set version); the GitHub release tag (`psc-0.15.15-<date>`)
identifies our revision. purs 0.15.16 against a 0.15.15-built set is the same
proven-compatible pairing pslua's `test/ps` already relies on.
- A fork tag bump flows through unchanged: bump `src/packages.json`, regenerate
the README table, refresh `latest-compatible-sets.json`, push a `psc-*` tag —
the release workflow emits `packages.json` (see [0006](0006-fork-release-by-annotated-tag.md)).
- Each fork's own build migrates to `spago.yaml` + spago 1.x (rolled out per
fork; CONTRIBUTING reflects the new toolchain). The Dhall formatter and the
`dhall` dev-shell tool leave each fork as part of that pass.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ The practical, do-this summary of these decisions is in the repository root
- [0005](0005-agents-md-single-source.md) — AGENTS.md is the single agent instruction file
- [0006](0006-fork-release-by-annotated-tag.md) — Release forks with annotated tags
- [0007](0007-formatting-treefmt-purs-tidy-lua-format.md) — Formatting via treefmt: purs-tidy and lua-format
- [0008](0008-new-spago-and-json-package-set.md) — Publish a consumable JSON package set for the new spago
2 changes: 1 addition & 1 deletion latest-compatible-sets.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"0.15.15": "psc-0.15.15-20260615-2"
"0.15.15": "psc-0.15.15-20260624"
}
Loading