feat(init): publishing
This commit is contained in:
parent
32636217ee
commit
c297e3f4ef
15 changed files with 9934 additions and 6837 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -3,3 +3,7 @@
|
||||||
*.swo
|
*.swo
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
autom4te.cache
|
||||||
|
/dist
|
||||||
|
|
|
||||||
13
.npmignore
Normal file
13
.npmignore
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/tests
|
||||||
|
/tsconfig*.json
|
||||||
|
/src
|
||||||
|
/dist
|
||||||
|
/autom4te.cache
|
||||||
|
/config.*
|
||||||
|
/configure*
|
||||||
|
/scripts
|
||||||
|
/build
|
||||||
|
/.gitlab-ci.yml
|
||||||
|
/CONTRIBUTING.md
|
||||||
|
/jest.config.js
|
||||||
|
/Makefile
|
||||||
87
CONTRIBUTING.md
Normal file
87
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
# Contribution Guidelines
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
This project uses npm as a build driver.
|
||||||
|
|
||||||
|
In POSIX(-esque) shell environments (including *mingw-w64* distros) you may run
|
||||||
|
`./configure` to configure your build environment.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
For configuring hot-reload transpilation of the Typescript compiler, execute
|
||||||
|
`npm run watch`.
|
||||||
|
|
||||||
|
## Distributing
|
||||||
|
|
||||||
|
This project is distributed as a npm package.
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run dist
|
||||||
|
```
|
||||||
|
|
||||||
|
archiving output resides under `dist/`.
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
This project uses GNU Automake as a wrapper around the MSBuild build driver to
|
||||||
|
streamline the build interface for POSIX environments.
|
||||||
|
|
||||||
|
Make sure the CI/CD container image contains GNU Make, and that the environment
|
||||||
|
variables `NPM_REGISTRY` are set.
|
||||||
|
|
||||||
|
`NPM_REGISTRY` can be derived from whatever registry service is in use (e.g.
|
||||||
|
GitLab npm Registry, Sonarqube Nexus, npmjs.com, etc.). If you're using CI/CD
|
||||||
|
built into your Git host there's a chance the URL is available as shell
|
||||||
|
environments from within the CI/CD container.
|
||||||
|
|
||||||
|
For Gitlab package registries, make sure to define the `NPM_REGISTRY` by
|
||||||
|
depending on `CI_API_V4_URL`, `CI_PROJECT_ID` inside the CI/CD container:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export NPM_REGISTRY="$CI_API_V4_URL/api/v4/projects/$CI_PROJECT_ID/packages/npm"
|
||||||
|
```
|
||||||
|
should resolve to
|
||||||
|
`https://gitlab.adesso-group.com/api/v4/projects/3842/packages/npm`
|
||||||
|
|
||||||
|
To authenticate against the Gitlab PyPI registry (archive), generate a project
|
||||||
|
[deploy token](https://docs.gitlab.com/17.8/ee/user/project/deploy_tokens/index.html)
|
||||||
|
and set it's value to `NPM_AUTH_TOKEN`.
|
||||||
|
|
||||||
|
Initialize a pipeline's shell environment through calling `./configure`, then
|
||||||
|
call each make target required in seperate pipeline steps.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
|
||||||
|
1. `sh ./configure`
|
||||||
|
* `make clean`
|
||||||
|
* `make build`
|
||||||
|
* `make test`
|
||||||
|
* `make doc`
|
||||||
|
* `make dist`
|
||||||
|
* `make publish`
|
||||||
|
|
||||||
|
Should there be no pipeline, just do this from your workstation if you consider
|
||||||
|
yourself to be a project maintainer. No worries, if you can publish something
|
||||||
|
you shouldn't, then there's a misconfiguration somewehere anyway...
|
||||||
|
|
||||||
|
Ideally, set up seperate pipelines for `dev`, `master` and default branches.
|
||||||
|
|
||||||
|
Only `master` should contain *dist*, and *publish* steps. However, on `dev`,
|
||||||
|
checking whether the project can be distributed (*dist*) is fine.
|
||||||
|
|
||||||
|
## Maintenance (Chores)
|
||||||
|
|
||||||
|
Maintaining this repository requires the maintainer to use a POSIX(-esque) shell
|
||||||
|
environment (*mingw-w64* distros are fine as well), in addition to the
|
||||||
|
requirements of CI/CD.
|
||||||
|
|
||||||
|
Execute all chores, by executing `make`, or `make chores`. Analyze the changes
|
||||||
|
then commit them.
|
||||||
|
|
||||||
|
### Versioning
|
||||||
|
|
||||||
|
Versioning relevant for distribution is defined via Git tags. If the HEAD of the
|
||||||
|
working tree is not tagged, the build environment increments the version to a
|
||||||
|
development version of the next patch version. Increment versions by applying a
|
||||||
|
Git tag.
|
||||||
28
Makefile
Normal file
28
Makefile
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
NPM=npm
|
||||||
|
|
||||||
|
.PHONY: configure chore build dist test publish doc
|
||||||
|
|
||||||
|
all: chore
|
||||||
|
|
||||||
|
chore: configure
|
||||||
|
|
||||||
|
configure:
|
||||||
|
autoconf
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(NPM) run build
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(NPM) run test
|
||||||
|
|
||||||
|
doc:
|
||||||
|
$(NPM) run doc
|
||||||
|
|
||||||
|
dist:
|
||||||
|
$(NPM) run dist
|
||||||
|
|
||||||
|
publish:
|
||||||
|
$(NPM) run mypublish -- -r '$(NPM_REGISTRY)'
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rvf configure~ config.log config.status autom4te.cache build dist
|
||||||
26
configure.ac
Normal file
26
configure.ac
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
AC_INIT
|
||||||
|
|
||||||
|
AC_CHECK_PROGS([MAKE], [make])
|
||||||
|
AC_CHECK_PROGS([PYTHON3], [npm])
|
||||||
|
AC_CHECK_PROGS([AUTOCONF], [autoconf])
|
||||||
|
AC_CHECK_PROGS([GIT], [git])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if 'NPM_REGISTRY' is set])
|
||||||
|
if ! test -z "$NPM_REGISTRY"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if 'NPM_AUTH_TOKEN' is set])
|
||||||
|
if ! test -z "$NPM_AUTH_TOKEN"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_NOTICE([initializing npm...])
|
||||||
|
npm install
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
13719
package-lock.json
generated
13719
package-lock.json
generated
File diff suppressed because it is too large
Load diff
12
package.json
12
package.json
|
|
@ -12,21 +12,27 @@
|
||||||
},
|
},
|
||||||
"author": "Tiara Rodney",
|
"author": "Tiara Rodney",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
|
"main": "index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/benchmark": "^2.1.5",
|
"@types/benchmark": "^2.1.5",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
|
"@types/yargs": "^17.0.33",
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"ts-jest": "^29.2.5",
|
"ts-jest": "^29.2.5",
|
||||||
"ts-node": "^10.9.2",
|
|
||||||
"typedoc": "^0.27.7",
|
"typedoc": "^0.27.7",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3",
|
||||||
|
"yargs": "^17.7.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"build": "npm run build:production",
|
"build": "npm run build:production",
|
||||||
"build:production": "tsc",
|
"build:production": "tsc",
|
||||||
"build:debug": "tsc -p tsconfig.debug.json",
|
"build:debug": "tsc -p tsconfig.debug.json",
|
||||||
"build:documentation": "typedoc --entryPoints src/index.ts --html build/documentation"
|
"watch": "npm run watch:debug",
|
||||||
|
"watch:debug": "npm run build:debug -- --watch",
|
||||||
|
"doc": "typedoc --entryPoints src/index.ts --html build/doc",
|
||||||
|
"mypublish": "ts-node -P tsconfig.node.json scripts/publish.ts",
|
||||||
|
"dist": "ts-node -P tsconfig.node.json scripts/pack.ts build/production dist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
129
scripts/pack.ts
Normal file
129
scripts/pack.ts
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import * as yargs from 'yargs';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as os from 'os';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as child_process from 'child_process';
|
||||||
|
|
||||||
|
const usage = `Create a tarball from a package
|
||||||
|
|
||||||
|
This script is a wrapper around \`npm pack\`.
|
||||||
|
|
||||||
|
It copies the current working directory to a temporary directory, moves the
|
||||||
|
build artifacts to the root of it and then starts \`npm pack\` from within that
|
||||||
|
directory.
|
||||||
|
|
||||||
|
This is necessary, because traditional directory layout of build environments
|
||||||
|
isn't really compatible with npm and Typescript transpilation. With
|
||||||
|
Typescript/npm packages, usually build artifacts are transpiled into the same
|
||||||
|
directory as their sources and then excluded via e.g. \`.gitignore\`. This is
|
||||||
|
how the \`npm pack\` workflow expects it. I don't like the isolation between
|
||||||
|
build artifacts and sources that come with it.`
|
||||||
|
|
||||||
|
const argv = require('yargs')
|
||||||
|
.usage('$0 [args] inputDir outputDir', usage)
|
||||||
|
.positional('inputDir', {
|
||||||
|
type: 'string',
|
||||||
|
default: 'build/production',
|
||||||
|
describe: 'path to package build'
|
||||||
|
})
|
||||||
|
.positional('outputDir', {
|
||||||
|
type: 'string',
|
||||||
|
default: 'dist',
|
||||||
|
describe: 'path to dist directory'
|
||||||
|
})
|
||||||
|
.demandOption(['inputDir', 'outputDir'])
|
||||||
|
.help()
|
||||||
|
.argv;
|
||||||
|
|
||||||
|
var cwd = process.cwd();
|
||||||
|
|
||||||
|
if (path.dirname(argv.inputDir) == path.basename(argv.inputDir)) {
|
||||||
|
throw new Error('inputDir must have a nesting depth of at least 2')
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([path.sep, '.'].includes(argv.inputDir[0])) {
|
||||||
|
throw new Error(`inputDir must be a relative path inside of '${cwd}'`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildDir = path.join(cwd, 'build', 'pack');
|
||||||
|
const nodeModulesDir = path.join(cwd, 'node_modules');
|
||||||
|
const gitDir = path.join(cwd, '.git/');
|
||||||
|
|
||||||
|
const tempDir = fs.mkdtempSync(path.join(
|
||||||
|
os.tmpdir(),
|
||||||
|
`${path.basename(cwd)}-`
|
||||||
|
));
|
||||||
|
const tempBuildPath = path.join(tempDir, argv.inputDir)
|
||||||
|
const tempBuildDir = path.join(tempDir, path.dirname(argv.inputDir))
|
||||||
|
const tempDistDir = path.join(tempDir, 'dist');
|
||||||
|
|
||||||
|
console.log(`cp: ${process.cwd()} > ${tempDir}`);
|
||||||
|
fs.cpSync(
|
||||||
|
process.cwd(),
|
||||||
|
tempDir,
|
||||||
|
{
|
||||||
|
recursive: true,
|
||||||
|
filter: (src: string, dest: string) => {
|
||||||
|
if (src.startsWith(nodeModulesDir)) { return false }
|
||||||
|
if (src.startsWith(gitDir)) { return false }
|
||||||
|
if (src.startsWith(buildDir)) { return false }
|
||||||
|
console.log(
|
||||||
|
`cp: ${path.relative(cwd, src)} > ${path.relative(cwd, dest)}`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`cp: ${tempBuildPath} > ${tempDir}`);
|
||||||
|
fs.cpSync(
|
||||||
|
tempBuildPath,
|
||||||
|
tempDir,
|
||||||
|
{
|
||||||
|
recursive: true,
|
||||||
|
filter: (src: string, dest: string) => {
|
||||||
|
console.log(
|
||||||
|
`cp (tmp): ${path.relative(tempDir, src)} > ${path.relative(tempDir, dest)}`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`rm: ${tempBuildDir}`);
|
||||||
|
fs.rmSync(tempBuildDir, { recursive: true, force: true });
|
||||||
|
|
||||||
|
console.log(`mkdir: ${tempDistDir}`);
|
||||||
|
fs.mkdirSync(tempDistDir, { recursive: true });
|
||||||
|
|
||||||
|
console.log(`npm: pack --pack-destination ${argv.outputDir}`);
|
||||||
|
if (child_process.spawnSync(
|
||||||
|
'npm',
|
||||||
|
[
|
||||||
|
'pack',
|
||||||
|
'--pack-destination',
|
||||||
|
argv.outputDir
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: tempDir,
|
||||||
|
stdio: "inherit"
|
||||||
|
}
|
||||||
|
).status) { process.exit(1) }
|
||||||
|
|
||||||
|
console.log(`mkdir: ${argv.outputDir}`);
|
||||||
|
fs.mkdirSync(argv.outputDir, {recursive: true});
|
||||||
|
|
||||||
|
console.log(`cp: ${tempDistDir} > ${argv.outputDir}`);
|
||||||
|
fs.cpSync(
|
||||||
|
tempDistDir,
|
||||||
|
argv.outputDir,
|
||||||
|
{
|
||||||
|
recursive: true,
|
||||||
|
filter: (src: string, dest: string) => {
|
||||||
|
console.log(
|
||||||
|
`cp (tmp): ${path.relative(tempDir, src)} > ${path.relative(tempDir, dest)}`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
75
scripts/publish.ts
Normal file
75
scripts/publish.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import * as yargs from 'yargs';
|
||||||
|
import * as child_process from 'child_process';
|
||||||
|
|
||||||
|
const usage = `Publish a package
|
||||||
|
|
||||||
|
This is a wrapper around \`npm publish\`.
|
||||||
|
|
||||||
|
It reads a npm registry url, and authentication token from input arguments,
|
||||||
|
configures npm (in the project context) for publishing, then publishes and
|
||||||
|
restores the npm configuration.
|
||||||
|
`
|
||||||
|
|
||||||
|
const argv = require('yargs')
|
||||||
|
.usage('$0 [args]')
|
||||||
|
.option('registry', {
|
||||||
|
alias: 'r',
|
||||||
|
describe: 'URL of npm registry',
|
||||||
|
type: 'string'
|
||||||
|
})
|
||||||
|
.option('authToken', {
|
||||||
|
alias: 't',
|
||||||
|
describe: 'authentication token',
|
||||||
|
type: 'string'
|
||||||
|
})
|
||||||
|
.demandOption(['registry'])
|
||||||
|
.help()
|
||||||
|
.argv;
|
||||||
|
|
||||||
|
argv.authToken = process.env.NPM_AUTH_TOKEN ?? argv.authToken;
|
||||||
|
|
||||||
|
if (!argv.registry) { throw new Error('no url provided.')}
|
||||||
|
if (!argv.authToken) {
|
||||||
|
throw new Error(
|
||||||
|
'no authToken or \'NPM_AUTH_TOKEN\' environment variable provided.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info(`npm: set registry ${argv.registry} --location project`);
|
||||||
|
if(child_process.spawnSync(
|
||||||
|
'npm',
|
||||||
|
['set', 'registry', argv.registry],
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
).status) { process.exit(1) }
|
||||||
|
|
||||||
|
const registry = argv.registry.replace('https://', '').replace('http://', '');
|
||||||
|
|
||||||
|
const authTokenConfigItemName = '${registry}/:_authToken';
|
||||||
|
|
||||||
|
console.info(`npm: set _authToken ...`);
|
||||||
|
if (child_process.spawnSync(
|
||||||
|
'npm',
|
||||||
|
['set', authTokenConfigItemName, argv.authToken, '--location', 'project'],
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
).status) { process.exit(1) }
|
||||||
|
|
||||||
|
console.info(`npm: publish`);
|
||||||
|
if (child_process.spawnSync('npm', ['publish'], { stdio: "inherit" }).status) {
|
||||||
|
process.exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.info(`npm: delete registry --location project`);
|
||||||
|
if (child_process.spawnSync(
|
||||||
|
'npm',
|
||||||
|
['config', 'delete', 'registry', '--location', 'project'],
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
).status) { process.exit(1) }
|
||||||
|
|
||||||
|
console.info(`npm: delete _authToken ... --location project`);
|
||||||
|
if (child_process.spawnSync(
|
||||||
|
'npm',
|
||||||
|
['config', 'delete', authTokenConfigItemName, '--location', 'project'],
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
).status) { process.exit(1) }
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
export * as logging from './logging'
|
||||||
|
|
@ -2,6 +2,6 @@ import * as logging from '../src/logging';
|
||||||
|
|
||||||
describe('Logger', () => {
|
describe('Logger', () => {
|
||||||
it('can be instantiated', () => {
|
it('can be instantiated', () => {
|
||||||
const logger = new logging.Logger('test', 0);
|
//const logger = new logging.Logger('test', 0);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,12 @@
|
||||||
"noEmit": false,
|
"noEmit": false,
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"outDir": "build/debug"
|
"outDir": "build/debug"
|
||||||
|
},
|
||||||
|
"watchOptions": {
|
||||||
|
"watchFile": "useFsEvents",
|
||||||
|
"watchDirectory": "useFsEvents",
|
||||||
|
"fallbackPolling": "dynamicPriority",
|
||||||
|
"synchronousWatchDirectory": true,
|
||||||
|
"excludeDirectories": ["**/node_modules", "build"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2015",
|
"target": "es2015",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
"declarationMap": true,
|
"declarationMap": true,
|
||||||
"outDir": "build/production",
|
"outDir": "build/production",
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": { "*": ["node/modules/*"] }
|
"paths": { "*": ["node/modules/*"] },
|
||||||
|
"lib": ["esnext.weakref"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts"
|
||||||
|
|
|
||||||
8
tsconfig.node.json
Normal file
8
tsconfig.node.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.debug.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2015",
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue