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
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
uses: actions/configure-pages@v5
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- uses: actions/cache@v4
id: cache
with:
Expand All @@ -50,4 +50,4 @@ jobs:
path: './gh-pages'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v4
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 19, 20, 21, 22, 23]
node-version: [22, 24, 26]
steps:
- uses: actions/checkout@v4

Expand All @@ -48,4 +48,4 @@ jobs:
- name: Run tests
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm test
run: npm test
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ Example statusboards using `@pkgjs/statusboard`:

## Setup

Requires Node.js 22 or newer. The CLI loads `.env` from the current directory
using Node.js's native environment file support. Use `--env <path>` to load a
different file. Existing environment variables take precedence, and the file
is optional when variables are provided by the shell or CI.

WARNING: work in process, the following doesn't work yet, but soon!

The easiest way to create a status board for your project is using Github Pages. To get started, create a new repo for your project and clone it
Expand Down Expand Up @@ -63,4 +68,4 @@ $ cd build && git add . && git commit -m "our new statuspage" && git push
- Typescript support (load typings or if authored in TS)
- People/Teams (specify and display teams, for example the express TC)
- GH CI status
- Pinned projects
- Pinned projects
4 changes: 2 additions & 2 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'
const yargs = require('yargs/yargs')
const dotenv = require('dotenv')
const loadEnv = require('./load-env')
const path = require('path')

const SHARED_OPTIONS = {
Expand Down Expand Up @@ -34,7 +34,7 @@ const SHARED_OPTIONS = {

function createBoard (create, argv) {
if (argv.env) {
dotenv.config(argv.env || '.env')
loadEnv(argv.env)
}

const opts = {}
Expand Down
11 changes: 11 additions & 0 deletions lib/load-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict'
const { loadEnvFile } = require('node:process')

module.exports = function loadEnv (file = '.env') {
try {
loadEnvFile(file)
} catch (error) {
// An env file is optional when variables are supplied by the environment.
if (error.code !== 'ENOENT') throw error
}
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
"@wesleytodd/buildjs": "0.0.8",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"cptmpl": "0.0.4",
"dotenv": "^17.2.0",
"es5-lit-element": "^2.2.1",
"es5-lit-html": "^1.1.1",
"express": "^5.2.1",
Expand All @@ -64,6 +63,6 @@
"yargs": "^17.7.2"
},
"engines": {
"node": ">=18"
"node": ">=22"
}
}
66 changes: 66 additions & 0 deletions test/cli-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use strict'
const { suite, test, beforeEach, afterEach } = require('mocha')
const assert = require('node:assert/strict')
const fs = require('node:fs/promises')
const os = require('node:os')
const path = require('node:path')
const { execFileSync } = require('node:child_process')

suite('CLI environment files', () => {
let directory

beforeEach(async () => {
directory = await fs.mkdtemp(path.join(os.tmpdir(), 'statusboard-env-'))
await fs.writeFile(path.join(directory, 'config.cjs'),
'module.exports = { tokenFromConfig: process.env.GITHUB_TOKEN }')
})

afterEach(async () => {
await fs.rm(directory, { recursive: true, force: true })
})

function runCli (args = [], token) {
const env = { ...process.env }
for (const key of ['GITHUB_TOKEN', 'GITHUB_USER', 'GITHUB_PASS', 'GITHUB_2FA']) {
delete env[key]
}
if (token) env.GITHUB_TOKEN = token
const script = `
const cli = require(${JSON.stringify(require.resolve('../lib/cli'))})
cli(async opts => {
process.stdout.write(JSON.stringify(opts))
return { buildSite: async () => {} }
}).parseAsync(['site', '--config', 'config.cjs', ...process.argv.slice(1)])
.catch(() => { process.exitCode = 1 })
`
return JSON.parse(execFileSync(process.execPath, ['-e', script, '--', ...args], {
cwd: directory,
env,
encoding: 'utf8'
}))
}

test('loads the default .env before reading configuration', async () => {
await fs.writeFile(path.join(directory, '.env'), 'GITHUB_TOKEN="from-file"\n')
const opts = runCli()
assert.equal(opts.github.token, 'from-file')
assert.equal(opts.tokenFromConfig, 'from-file')
})

test('honors --env instead of loading the default file', async () => {
await fs.writeFile(path.join(directory, '.env'), 'GITHUB_TOKEN=default\n')
await fs.writeFile(path.join(directory, 'custom.env'), 'GITHUB_TOKEN=custom\n')
const opts = runCli(['--env', 'custom.env'])
assert.equal(opts.github.token, 'custom')
assert.equal(opts.tokenFromConfig, 'custom')
})

test('preserves variables supplied by the environment', async () => {
await fs.writeFile(path.join(directory, '.env'), 'GITHUB_TOKEN=from-file\n')
assert.equal(runCli([], 'from-shell').github.token, 'from-shell')
})

test('works without an .env file when the token is supplied externally', () => {
assert.equal(runCli([], 'from-ci').github.token, 'from-ci')
})
})
2 changes: 1 addition & 1 deletion test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict'
require('dotenv').config()
require('../lib/load-env')()
const { suite, test, before } = require('mocha')
const assert = require('assert')
const fs = require('fs-extra')
Expand Down
Loading