Skip to content
Draft
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
105 changes: 53 additions & 52 deletions .github/workflows/web-demos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ jobs:
~/.npm
~/.cargo/registry
~/.cargo/git
~/.ghc-wasm/.cabal
target
dist-newstyle
key: web-demos-${{ runner.os }}-${{ hashFiles('flake.lock', 'Cargo.lock', 'cabal.project', 'packages/**/*.cabal', 'packages/coln-js-runtime/package-lock.json', 'examples/sync-demo/pnpm-lock.yaml') }}
key: web-demos-${{ runner.os }}-${{ hashFiles('flake.lock', 'Cargo.lock', 'packages/coln-js-runtime/package-lock.json', 'examples/sync-demo/pnpm-lock.yaml') }}
restore-keys: |
web-demos-${{ runner.os }}-

Expand All @@ -55,57 +53,60 @@ jobs:
env:
VITE_BASE: /sync/

- name: Build web compiler
run: |
nix develop --accept-flake-config --command wasm32-wasi-cabal update 'hackage.haskell.org,2026-07-15T17:07:49Z'
nix develop --accept-flake-config --command just examples/build-web-compiler
# TODO commented out to prevent CI compiling a GHC from source
# - name: Build web compiler
# run: |
# nix build --accept-flake-config .#web-compiler
# mkdir -p _build/web
# cp -rL result _build/web/compiler
# chmod -R u+w _build/web/compiler

- name: Assemble deploy directory
run: |
cp examples/index.html examples/style.css _build/web/
cp -r examples/sync-demo/dist _build/web/sync
# - name: Assemble deploy directory
# run: |
# cp examples/index.html examples/style.css _build/web/
# cp -r examples/sync-demo/dist _build/web/sync

- name: Deploy PR preview to Netlify
id: deploy-preview
if: github.event_name == 'pull_request' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != ''
run: |
npx --yes netlify-cli@latest deploy \
--auth "$NETLIFY_AUTH_TOKEN" \
--site "$NETLIFY_SITE_ID" \
--dir _build/web \
--no-build \
--alias "pr-${{ github.event.pull_request.number }}" \
--message "PR #${{ github.event.pull_request.number }} web demos" \
--json > netlify-deploy.json
# - name: Deploy PR preview to Netlify
# id: deploy-preview
# if: github.event_name == 'pull_request' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != ''
# run: |
# npx --yes netlify-cli@latest deploy \
# --auth "$NETLIFY_AUTH_TOKEN" \
# --site "$NETLIFY_SITE_ID" \
# --dir _build/web \
# --no-build \
# --alias "pr-${{ github.event.pull_request.number }}" \
# --message "PR #${{ github.event.pull_request.number }} web demos" \
# --json > netlify-deploy.json

cat netlify-deploy.json
deploy_url=$(node -e "const d = require('./netlify-deploy.json'); console.log(d.deploy_ssl_url || d.ssl_url || d.deploy_url || d.url)")
echo "deploy-url=$deploy_url" >> "$GITHUB_OUTPUT"
# cat netlify-deploy.json
# deploy_url=$(node -e "const d = require('./netlify-deploy.json'); console.log(d.deploy_ssl_url || d.ssl_url || d.deploy_url || d.url)")
# echo "deploy-url=$deploy_url" >> "$GITHUB_OUTPUT"

- name: Comment with deploy preview URL
if: github.event_name == 'pull_request' && steps.deploy-preview.outputs.deploy-url != ''
uses: actions/github-script@v8
with:
script: |
const marker = '<!-- coln-web-demos-deploy-preview -->'
const body = `${marker}\nWeb demo preview: ${{ steps.deploy-preview.outputs.deploy-url }}`
const { owner, repo } = context.repo
const issue_number = context.issue.number
const comments = await github.rest.issues.listComments({ owner, repo, issue_number, per_page: 100 })
const existing = comments.data.find(comment => comment.body?.includes(marker))
if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body })
} else {
await github.rest.issues.createComment({ owner, repo, issue_number, body })
}
# - name: Comment with deploy preview URL
# if: github.event_name == 'pull_request' && steps.deploy-preview.outputs.deploy-url != ''
# uses: actions/github-script@v8
# with:
# script: |
# const marker = '<!-- coln-web-demos-deploy-preview -->'
# const body = `${marker}\nWeb demo preview: ${{ steps.deploy-preview.outputs.deploy-url }}`
# const { owner, repo } = context.repo
# const issue_number = context.issue.number
# const comments = await github.rest.issues.listComments({ owner, repo, issue_number, per_page: 100 })
# const existing = comments.data.find(comment => comment.body?.includes(marker))
# if (existing) {
# await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body })
# } else {
# await github.rest.issues.createComment({ owner, repo, issue_number, body })
# }

- name: Deploy main to Netlify production
if: github.event_name == 'push' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != ''
run: |
npx --yes netlify-cli@latest deploy \
--auth "$NETLIFY_AUTH_TOKEN" \
--site "$NETLIFY_SITE_ID" \
--dir _build/web \
--no-build \
--prod \
--message "web demos ${{ github.sha }}"
# - name: Deploy main to Netlify production
# if: github.event_name == 'push' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != ''
# run: |
# npx --yes netlify-cli@latest deploy \
# --auth "$NETLIFY_AUTH_TOKEN" \
# --site "$NETLIFY_SITE_ID" \
# --dir _build/web \
# --no-build \
# --prod \
# --message "web demos ${{ github.sha }}"
3 changes: 3 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ jobs: $ncpus
semaphore: true
tests: True

if os(wasi)
shared: True

constraints:
-- Cabal otherwise sometimes picks bad build plans due to faulty metadata in older versions of these libs:
-- https://github.com/haskell/lsp/issues/641
Expand Down
87 changes: 8 additions & 79 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 52 additions & 5 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
nixpkgs.url = "github:georgefst/nixpkgs/ghc-wasm";
flake-utils.url = "github:numtide/flake-utils";
rust-overlay.url = "github:oxalica/rust-overlay";
ghc-wasm-meta.url = "gitlab:haskell-wasm/ghc-wasm-meta?host=gitlab.haskell.org";
};
outputs =
inputs@{
Expand Down Expand Up @@ -135,6 +134,29 @@
'';
};

# TODO find some way to DRY this with `just examples/build-web-compiler`
# TODO do the combined web-demo build in Nix, removing logic from YAML
web-compiler = pkgs.runCommand "coln-web-compiler"
{
nativeBuildInputs = [
pkgs.nodejs
pkgs.jq
];
}
''
dist=$out/dist
mkdir -p $dist
cp ${wasmColnPackages.coln-compiler-wasm}/bin/coln-compiler-wasm* $dist/coln.wasm
libdir=$(${wasmHaskellPackages.ghc}/bin/${wasmHaskellPackages.ghc.targetPrefix}ghc --print-libdir)
node "$libdir/post-link.mjs" --input $dist/coln.wasm --output $dist/ghc_wasm_jsffi.js
cp ${./packages/coln-compiler-wasm/loadHaskellWasm.js} $dist/loadHaskellWasm.js
cp ${./examples/compiler-demo/index.html} $out/index.html
cp ${./examples/style.css} $out/style.css
mkdir -p $out/examples
cp ${./packages/coln-compiler/test/golden}/*.coln $out/examples/
ls -1 $out/examples/*.coln | xargs -n1 basename | jq -nR '[inputs]' > $out/examples/index.json
'';

format-hs = nuShellCheck [pkgs.fourmolu] ./nix/checks/format-hs.nu;
format-cabal = nuShellCheck [pkgs.haskellPackages.cabal-gild] ./nix/checks/format-cabal.nu;

Expand Down Expand Up @@ -189,7 +211,30 @@


inherit (packages) forester coln-manual-dev;
haskell-wasm = inputs.ghc-wasm-meta.packages.${system};
# TODO DRY with native builds
wasmHaskellPackages = pkgs.pkgsCross.wasi32.haskell.packages.ghc9141.override {
overrides = _: prev: {
# mirrors cabal.project
# TODO these are actually about GHC 9.14 compatibility rather than Wasm
ordered-containers = pkgs.haskell.lib.doJailbreak prev.ordered-containers;
prettyprinter-lucid = pkgs.haskell.lib.doJailbreak prev.prettyprinter-lucid;
};
};
wasmColnPackages = rec {
diagnostician = wasmHaskellPackages.callPackage ./packages/diagnostician { };
diagnostician-html = wasmHaskellPackages.callPackage ./packages/diagnostician-html {
inherit diagnostician;
};
fnotation = wasmHaskellPackages.callPackage ./packages/fnotation {
inherit diagnostician;
};
coln-compiler = wasmHaskellPackages.callPackage ./packages/coln-compiler {
inherit diagnostician fnotation;
};
coln-compiler-wasm = wasmHaskellPackages.callPackage ./packages/coln-compiler-wasm {
inherit coln-compiler diagnostician diagnostician-html fnotation;
};
};
lsTsDir = ./packages/coln-ls/client;
lsClientNpmDeps = pkgs.importNpmLock {
npmRoot = lsTsDir;
Expand Down Expand Up @@ -221,8 +266,10 @@
forester
fourmolu
esbuild
haskell-wasm.wasm32-wasi-ghc-9_14
haskell-wasm.wasm32-wasi-cabal-9_14
wasmHaskellPackages.ghc
(pkgs.writeShellScriptBin "wasm32-unknown-wasi-cabal" ''
exec ${pkgs.cabal-install}/bin/cabal --with-compiler=${wasmHaskellPackages.ghc.unprefixed}/bin/ghc "$@"
'')
haskell.compiler.ghc912
haskell.packages.ghc912.haskell-language-server
haskellPackages.cabal-gild
Expand Down
17 changes: 17 additions & 0 deletions packages/coln-compiler-wasm/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{ mkDerivation, aeson, base, coln-compiler, containers
, diagnostician, diagnostician-html, fnotation, ghc-experimental
, lib, lucid, ordered-containers, prettyprinter, text
}:
mkDerivation {
pname = "coln-compiler-wasm";
version = "0.1";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [
aeson base coln-compiler containers diagnostician
diagnostician-html fnotation ghc-experimental lucid
ordered-containers prettyprinter text
];
license = "(Apache-2.0 OR MIT)";
}
6 changes: 3 additions & 3 deletions packages/coln-compiler-wasm/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ build:
#!/usr/bin/env bash
set -euxo pipefail
mkdir -p {{ dist_dir }}
wasm32-wasi-cabal build coln-compiler-wasm
cp "$(wasm32-wasi-cabal list-bin coln-compiler-wasm)" {{ dist_dir }}/coln.wasm
libdir="$(wasm32-wasi-ghc --print-libdir)"
wasm32-unknown-wasi-cabal build coln-compiler-wasm
cp "$(wasm32-unknown-wasi-cabal list-bin coln-compiler-wasm)" {{ dist_dir }}/coln.wasm
libdir="$(wasm32-unknown-wasi-ghc --print-libdir)"
"$libdir/post-link.mjs" --input {{ dist_dir }}/coln.wasm --output {{ dist_dir }}/ghc_wasm_jsffi.js
cp loadHaskellWasm.js {{ dist_dir }}/loadHaskellWasm.js
Loading