-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
68e627d
commit 441916a
Showing
28 changed files
with
1,967 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# Contribution Guide | ||
|
||
- [Conventions](#conventions) | ||
- [Publishing](#publishing) | ||
- [Design goals](#design-goals) | ||
|
||
## Conventions | ||
|
||
- [Github Flow][gh-flow] | ||
- [Conventional Commits][ccom] | ||
- [Semver][sv] | ||
|
||
## Publishing | ||
|
||
Only via [Github Releases][gh-rel] which auto-publish to [npm][npm]. | ||
|
||
> example: publishing a new release: | ||
```bash | ||
gh release create v1.7.1 | ||
``` | ||
|
||
List current releases: | ||
|
||
```bash | ||
gh release list | ||
``` | ||
|
||
> note: versions must use format: `vX.X.X` & strictly follow [Semver][sv]. | ||
## Design goals | ||
|
||
> The key words: *"must"*, *"must not"*, *"should"*, *"should not"* & *"may"* | ||
> within this section, are to be interpreted as described in [RFC 2119][2119]. | ||
The following goals are *central* to this implementation: | ||
|
||
- [Zero maintenance](#zero-maintenance) | ||
- [Minimal API](#minimal-api) | ||
- [Robust](#robust) | ||
|
||
Trade-offs may be made in any aspect except the above. | ||
|
||
### Zero Maintenance | ||
|
||
> Designed to be safe for long-term use without any maintenance, even across | ||
> NodeJS versions. | ||
> Any warnings, security advisories etc. are considered failures. | ||
- Must not have dependencies, in any form: | ||
- no runtime dependencies | ||
- no `devDependencies` | ||
- no 3rd party services, i.e: coveralls | ||
- Must not use proposal-stage language features | ||
- Should not use Node APIs, i.e: `fs` | ||
- Must add a README indicator of tests status | ||
- CI must run tests on: | ||
- `engine` Node version. | ||
- `latest` Node version. | ||
|
||
### Minimal API | ||
|
||
> An API so minimal you won't need to look it up twice. Do one thing in one way. | ||
> No bells & whistles. Non-configurable.[^1] | ||
- Must not implement extras | ||
- Must not allow configuration | ||
- Should be concise instead of detailed | ||
- Must use native APIs where applicable: | ||
- i.e: Assume a feature i.e: *"Get instance `JSON`"*: | ||
- `JSON.stringify(fsm)` is idiomatic, well-known & easy to remember. Good. | ||
- `fsm.asJSON()` is specific to us, must be looked-up & memorised. Bad. | ||
|
||
### Robust | ||
|
||
> Throws validation errors unless input is given in an exact format. | ||
> Any failures after accepting the input should be treated as a bug. | ||
- Must implement a high-quality unit test suite: | ||
- Should use plainly-worded test cases, avoid technical details | ||
- Should use consistent language and test file structure | ||
- Should be modular, use file structure to split into distinct aspects | ||
- Must test only output. Must not test how it was obtained | ||
- Should have self-contained test files, can ignore DRY principle | ||
- Should not have complicated setups/mocks etc | ||
- Should not include imperative logic | ||
- Should have descriptive error messages with expected & actual values | ||
- Must have `> 95%` test-coverage & fail the entire suite if not | ||
- Must run in `< 2 seconds`, at most | ||
- Should only test public APIs | ||
- Must catch errors at *construction time* via strict validations | ||
- Must resolve ambiguity by throwing an `Error`. Don't assume. | ||
- Must `throw` on "okay-ish" arguments, don't attempt to normalise input | ||
- Must `throw` if a property/method exists and will be overwriten | ||
- Must only throw an `instanceof Error` | ||
- Must seal internal structure | ||
- Must hide private methods & state via `enumerable: false` | ||
|
||
## Authors | ||
|
||
[@nicholaswmin][nicholaswmin] | ||
|
||
## Footnotes | ||
|
||
[^1]: Not a variation of [Sensible Defaults][sd]. | ||
Here, we're not allowing *any* configuration. | ||
|
||
[nicholaswmin]: https://github.com/nicholaswmin | ||
[sv]: https://semver.org/ | ||
[sd]: https://en.wikipedia.org/wiki/Convention_over_configuration | ||
[gh-flow]: https://docs.github.com/en/get-started/using-github/github-flow | ||
[provenance]: https://docs.npmjs.com/generating-provenance-statements | ||
[ccom]: https://www.conventionalcommits.org/en/v1.0.0/ | ||
[2119]: https://www.ietf.org/rfc/rfc2119.txt | ||
[gh-rel]: https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases | ||
[npm]: https://www.npmjs.com/package/@nicholaswmin/fsm?activeTab=versions | ||
[repo-rels]: https://github.com/nicholaswmin/fsm/releases |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Security | ||
|
||
Vulnerabilities should be reported via the following process: | ||
|
||
- Open a Github Issue & mention it's about a vulnerability, but **do not** post | ||
the actual vulnerability itself. | ||
- The authors should suggest a private channel to discuss further. | ||
|
||
> Note: Only the latest versions receive security fixes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# - npm publish --provenance, from a `gh release` | ||
# - attaches package details on the Release notes | ||
|
||
name: npm:publish | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
on: | ||
release: | ||
types: | ||
- published | ||
|
||
jobs: | ||
npm-publish: | ||
runs-on: ubuntu-latest | ||
env: | ||
REL_VERSION: ${{ github.event.release.tag_name }} | ||
REL_BODY: ${{ github.event.release.body }} | ||
permissions: | ||
contents: write | ||
id-token: write | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Setup latest Node | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 'latest' | ||
registry-url: 'https://registry.npmjs.org' | ||
|
||
- name: Set Actions Bot as Git user | ||
run: | | ||
bot_email="41898282+github-actions[bot]@users.noreply.github.com" | ||
git config --global user.name github-actions[bot] | ||
git config --global user.email "$bot_email" | ||
- name: Bump package version | ||
run: | | ||
npm version "$REL_VERSION" -m "build: bump %s" --allow-same-version | ||
git pull origin HEAD:main | ||
git push origin HEAD:main | ||
- name: Publish on npm with provenance | ||
run: npm publish --provenance --access public | ||
|
||
- name: Append package to Release notes | ||
run: | | ||
pkg_name=$(npm pkg get name | tr -d '"') | ||
base_link="https://npmjs.com/package/${pkg_name}" | ||
pkg_link="[${pkg_name}](${base_link})" | ||
prov_link="[provenance](${base_link}#provenance)" | ||
markdown="Published: ${pkg_link} with build ${prov_link}." | ||
new_notes=$(printf "%s\n\n${REL_BODY}", "$markdown") | ||
gh release edit "$REL_VERSION" -n "${new_notes}" | ||
env: | ||
GH_TOKEN: ${{ github.token }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# unpublish from npm if it's Github Release was deleted/unpublished. | ||
|
||
name: npm:unpublish | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
on: | ||
release: | ||
types: | ||
- deleted | ||
- unpublished | ||
|
||
jobs: | ||
npm-unpublish: | ||
runs-on: ubuntu-latest | ||
env: | ||
REL_VERSION: ${{ github.event.release.tag_name }} | ||
permissions: | ||
contents: write | ||
id-token: write | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Setup latest Node | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 'latest' | ||
registry-url: 'https://registry.npmjs.org' | ||
|
||
- name: Unpublish from npm | ||
run: | | ||
n_version=$(echo "$REL_VERSION" | sed 's/[^0-9.]*//g') | ||
pckg_name="$(npm pkg get name | tr -d '"')" | ||
versioned="$pckg_name"@"$n_version" | ||
output=$(npm unpublish "$versioned") | ||
printf "::notice title=Unpublished ${versioned}::Output: ${output}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: tests:codeql | ||
|
||
on: | ||
push: | ||
branches: [ "main" ] | ||
pull_request: | ||
branches: [ "main" ] | ||
schedule: | ||
- cron: '44 11 * * 1' | ||
|
||
jobs: | ||
analyze: | ||
name: Analyze (${{ matrix.language }}) | ||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} | ||
timeout-minutes: 20 | ||
permissions: | ||
security-events: write | ||
packages: read | ||
actions: read | ||
contents: read | ||
|
||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- language: javascript-typescript | ||
build-mode: none | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Initialize CodeQL | ||
uses: github/codeql-action/init@v3 | ||
with: | ||
languages: ${{ matrix.language }} | ||
build-mode: ${{ matrix.build-mode }} | ||
|
||
- name: Perform CodeQL Analysis | ||
uses: github/codeql-action/analyze@v3 | ||
with: | ||
category: "/language:${{matrix.language}}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: tests:lint | ||
|
||
on: | ||
push: | ||
branches: [ "main" ] | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
lint: | ||
name: lint | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 5 | ||
strategy: | ||
matrix: | ||
node-version: [latest] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
cache: 'npm' | ||
|
||
- run: npm ci | ||
|
||
- run: npx -y eslint **/*.js --no-config-lookup | ||
name: Run ESLint with defaults |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: tests:unit | ||
|
||
on: | ||
push: | ||
branches: [ "main" ] | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
test: | ||
name: unit | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 5 | ||
strategy: | ||
matrix: | ||
node-version: [22.9, latest] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Use NodeJS - ${{ matrix.node-version }} | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
cache: 'npm' | ||
- run: npm ci | ||
- run: node --run test | ||
name: Run unit tests | ||
env: | ||
NODE_ENV: test |
Oops, something went wrong.