diff --git a/.woodpecker.yml b/.woodpecker.yml index 5664fb3..ae600e4 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,7 +1,8 @@ pipeline: build: - image: node:18-slim + image: node:18-alpine commands: + - apk add --no-cache git - npm ci - npm run build prepare_release: diff --git a/esbuildconf.js b/esbuildconf.js index a59d41d..7da29f3 100644 --- a/esbuildconf.js +++ b/esbuildconf.js @@ -3,12 +3,15 @@ import { createRequire } from 'module'; import alias from 'esbuild-plugin-alias'; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; +import { replaceOnCopyPlugin } from './tools/esbuild-helper.js' + // see docs at https://esbuild.github.io/api/ export const options = { entryPoints: [ 'src/main.js', 'src/main.css', 'src/index.html', + 'src/about.html', 'src/assets/comment.svg', 'src/assets/heart-fill.svg', 'src/assets/star.svg', @@ -31,7 +34,8 @@ export const options = { // cipher-base require's "stream" stream: createRequire(import.meta.url).resolve('readable-stream') }), - NodeGlobalsPolyfillPlugin({buffer: true}) + NodeGlobalsPolyfillPlugin({buffer: true}), + replaceOnCopyPlugin(/about\.html$/), ] }; diff --git a/src/about.html b/src/about.html new file mode 100644 index 0000000..752cbec --- /dev/null +++ b/src/about.html @@ -0,0 +1,24 @@ + + + + + + about / nostr + + + +
+

nostr: notes and other stuff transmitted by relays

+ this is a nostr web client.
+ source code is at git.qcode.ch/nostr/nostrweb. +

+ you are looking at version #[PKG_VERSION]#, built at git commit + #[GIT_COMMIT]#. +

+

+ for more information about nostr protocol, check out + nostr.info. +

+
+ + diff --git a/src/main.css b/src/main.css index 0948518..e527fb2 100644 --- a/src/main.css +++ b/src/main.css @@ -88,6 +88,10 @@ img { max-width: 100%; } +main.text { + margin: 2rem; +} + .danger { background-color: var(--bgcolor-danger); } diff --git a/tools/esbuild-helper.js b/tools/esbuild-helper.js new file mode 100644 index 0000000..73478e8 --- /dev/null +++ b/tools/esbuild-helper.js @@ -0,0 +1,47 @@ +import { readFile } from 'node:fs/promises'; +import { execFile } from 'node:child_process'; +import { promisify } from 'node:util'; +const execFileAsync = promisify(execFile); + +/** + * replaceOnCopyPlugin is an esbuild plugin. it loads files as utf-8 text + * and replaces certain placeholders with their values computed on plugin setup. + * the fileFilter is a regexp matching names or extensions of the files to process, + * passed to esbuild's onLoad as is. + * + * the following placeholders are replaced: + * + * #[PKG_VERSION]# -> npm package version + * #[GIT_COMMIT]# -> short git commit at current HEAD + */ +export function replaceOnCopyPlugin(fileFilter) { + return { + name: 'replace-on-copy', + setup(build) { + const appVersion = sanitizedStr(process.env.npm_package_version); + const gitHeadCommit = gitRevParse('HEAD'); + + build.onLoad({filter: fileFilter}, async (args) => { + const gitCommitHash = await gitHeadCommit; + let text = await readFile(args.path, 'utf8'); + text = text.replaceAll('#[PKG_VERSION]#', appVersion); + text = text.replaceAll('#[GIT_COMMIT]#', gitCommitHash); + return { + contents: text, + loader: 'copy', + } + }); + } + } +} + +async function gitRevParse(rev) { + rev = sanitizedStr(rev); + const { stdout } = await execFileAsync('git', ['rev-parse', '--short', rev]); + return sanitizedStr(stdout.trim()); +} + +function sanitizedStr(s) { + const notOk = /[^0-9a-z \.@-]/ig; + return s.replaceAll(notOk, '-'); +}