Skip to content

Commit

Permalink
clean up, document, rename
Browse files Browse the repository at this point in the history
  • Loading branch information
echo-bravo-yahoo committed Oct 25, 2024
1 parent f7c30fc commit 695d5ee
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 35 deletions.
32 changes: 6 additions & 26 deletions .github/workflows/build-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: Build binaries
on:
push:
branches: [build]
pull_request:
branches: [build]

jobs:
build-binaries:
Expand Down Expand Up @@ -39,41 +37,23 @@ jobs:
- uses: actions/upload-artifact@v4
with:
# Name of the artifact to upload.
# Optional. Default is 'artifact'
name: fauna-shell-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.node }}

# A file, directory or wildcard pattern that describes what to upload
# Required.
path: ${{ matrix.os == 'windows' && 'dist\fauna.exe' || 'dist/fauna' }}

# The desired behavior if no files are found using the provided path.
# Available Options:
# warn: Output a warning but do not fail the action
# error: Fail the action with an error message
# ignore: Do not output any warnings or errors, the action does not fail
# Optional. Default is 'warn'
# Fail the action with an error message if no files are found at the path.
if-no-files-found: error

# Duration after which artifact will expire in days. 0 means using default retention.
# Minimum 1 day.
# Maximum 90 days unless changed from the repository settings page.
# Optional. Defaults to repository settings.
retention-days: 1
# Duration after which artifact will expire in days. 0 means use the repository's default retention.
retention-days: 0

# The level of compression for Zlib to be applied to the artifact archive.
# The value can range from 0 to 9.
# For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads.
# Optional. Default is '6'
# The level of compression for Zlib to be applied to the artifact archive from 0 (none) to 9 (most).
compression-level: 6

# If true, an artifact with a matching name will be deleted before a new one is uploaded.
# If false, the action will fail if an artifact for the given name already exists.
# Deletes any artifact with a matching name before a new one is uploaded.
# Does not fail if the artifact does not exist.
# Optional. Default is 'false'
overwrite: true

# Whether to include hidden files in the provided path in the artifact
# The file contents of any hidden files in the path should be validated before
# enabled this to avoid uploading sensitive information.
# Optional. Default is 'false'
# Don't upload hidden files in the provided path.
include-hidden-files: false
4 changes: 4 additions & 0 deletions DEV-README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### Application versions
This project has 3 runnable entrypoints (a raw ESM one, a built CJS one, and an SEA one). You can read more about them [here](./sea/README.md).

### General style guidelines
- Prefer to throw errors instead of exiting the process. Exit is harder to mock well in tests, and the global error-handler in `src/cli.mjs` should already do verbosity-aware error-handling. You can request a specific exit code by attaching an `exitCode` property to your error before throwing it. The error-handling has a series of tests in `yargs-test/general-cli.mjs`; if you find a case where throwing results in bad output to the user, replicate that case in a test suite.
- Prefer to re-throw an existing error after modifying its message over catching and throwing a newly-constructed error. The `exitCode` and `stack` properties on the existing error are worth keeping.
Expand All @@ -13,3 +16,4 @@
- `--verbose-component foo`, which logs all debug info for the component `foo`. Because it's an array, you can specify it multiple times. To see the available components, look at the help or tab completion.
- `--verbosity level`, where `level` is a number from 0 (no debug logging) to 5 (all debug logging) for all components.
- To investigate why a sinon stub is failing in a way you don't expect, you can log out `stub.args`, which is an array of the arguments provided each time the stub was called. This can be particularly helpful for assertions where the error message is hard to read or involves objects that don't stringify correctly (like FormData).
- To trigger [SEA builds](./sea/README.md) on all supported OS/architecture combinations, make changes and push commits to the `build` branch in github. This will [trigger github actions](./.github/workflows/build-binaries.yml) that build the SEA binaries.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"test:local": "mocha --recursive ./test --require ./test/mocha-root-hooks.mjs",
"build": "npm run build:app && npm run build:sea",
"build:app": "esbuild --bundle ./src/user-entrypoint.mjs --platform=node --outfile=./dist/cli.cjs --format=cjs --inject:./sea/import-meta-url.js --define:import.meta.url=importMetaUrl",
"build:sea": "node ./sea/build-sea.cjs",
"build:sea": "node ./sea/build.cjs",
"format": "prettier -w src test package.json prettier.config.js eslint.config.mjs"
},
"husky": {
Expand Down
17 changes: 17 additions & 0 deletions sea/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
### SEA (single executable application)
This directory contains the infrastructure for building `fauna-shell` as a single executable application. You can find the docs for SEA [here](https://nodejs.org/docs/latest-v22.x/api/single-executable-applications.html#single-executable-applications); since this feature is experimental, make sure you're looking at the same nodeJS version as the project uses; there will be breaking changes across nodeJS versions.

The process generally looks like this:

1. A developer (or CI) runs [npm run build](../package.json).
2. `build:app` runs `eslint` to build the ES module CLI into a single-file CJS module with its dependencies' inlined. There are a few wrinkles here with `import.meta.url` and `__dirname`, but it's otherwise fairly straight-forward. This is what `./sea/import-meta-url.js` is for.
3. `build:sea` runs `./sea/build.cjs`. This nodeJS script detects the OS and builds an SEA for that OS. One of the inputs to this process is `./sea/config.json`, which specifies some paths and settings for the resulting build. We could optimize our builds here by enabling `useSnapshot` and `useCodeCache`, but that's likely not worth the effort until we have a (basic) perf benchmark in place.

### Versions of the CLI
1. The raw (runnable!) ESM CLI can be invoked by `./src/user-entrypoint.mjs <command> [subcommand] [args]`.
2. The built CJS CLI can be invoked by `./dist/cli.cjs <command> [subcommand] [args]`.
3. The SEA CLI can be invoked by `./dist/fauna <command> [subcommand] [args]`.

### Differences between versions
_All 3 versions should be runnable and behave the same, with these exceptions:_
- Currently, no exceptions.
6 changes: 3 additions & 3 deletions sea/build-sea.cjs → sea/build.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if (platform === "linux") {
}

function buildSEAForLinux() {
run("node --experimental-sea-config ./sea/sea-config.json");
run("node --experimental-sea-config ./sea/config.json");
fs.copyFileSync(process.execPath, "./dist/fauna");
run(
"npx postject ./dist/fauna NODE_SEA_BLOB ./dist/sea.blob \
Expand All @@ -28,7 +28,7 @@ function buildSEAForLinux() {
}

function buildSEAForMac() {
run("node --experimental-sea-config ./sea/sea-config.json");
run("node --experimental-sea-config ./sea/config.json");
fs.copyFileSync(process.execPath, "./dist/fauna");
run("codesign --remove-signature ./dist/fauna");
run(
Expand All @@ -41,7 +41,7 @@ function buildSEAForMac() {
}

function buildSEAForWindows() {
run("node --experimental-sea-config .\\sea\\sea-config.json");
run("node --experimental-sea-config .\\sea\\config.json");
fs.copyFileSync(process.execPath, ".\\dist\\fauna.exe");
// more details on signing:
// https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-temporary-certificates-for-use-during-development#installing-a-certificate-in-the-trusted-root-certification-authorities-store
Expand Down
7 changes: 7 additions & 0 deletions sea/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"main": "./dist/cli.cjs",
"output": "./dist/sea.blob",
"disableExperimentalSEAWarning": true,
"useSnapshot": false,
"useCodeCache": false,
}
3 changes: 3 additions & 0 deletions sea/import-meta-url.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
// this is being used as an eslint plugin to map from CJS' __filename/__dirname
// to ESM's meta.import.url. this lets us write statements using meta.import.url
// in our source code that actually use CJS primitives after build.
export let importMetaUrl = require('url').pathToFileURL(__filename);
5 changes: 0 additions & 5 deletions sea/sea-config.json

This file was deleted.

0 comments on commit 695d5ee

Please sign in to comment.