diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ccc429b..cdc592f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,12 +16,41 @@ build: - node bin/nxapi.js util validate-discord-titles - - "node -e \"fs.writeFileSync('package.json', JSON.stringify((json => {json.__nxapi_release = process.env.CI_COMMIT_TAG; return json;})(JSON.parse(fs.readFileSync('package.json', 'utf-8'))), null, 4) + '\\n', 'utf-8')\"" + - export VERSION=`[ "$CI_COMMIT_BRANCH" != "main" ] || node resources/build/ci-main-version.js` + - "node -e \"fs.writeFileSync('package.json', JSON.stringify((json => {json.version = process.env.VERSION || json.version; json.__nxapi_release = process.env.CI_COMMIT_TAG; return json;})(JSON.parse(fs.readFileSync('package.json', 'utf-8'))), null, 4) + '\\n', 'utf-8')\"" - PACKAGE=`npm --color="always" pack` - mv "$PACKAGE" nxapi.tgz - npx electron-builder build --macos zip --linux --publish never - mv dist/app/package app + + - | + if [ "$CI_COMMIT_BRANCH" = "main" && "$VERSION" != "" ]; then + if [ "$NPM_PUBLISH_NEXT" = "true" && "$NPM_TOKEN" != "" ]; then + echo "Publishing $VERSION to npm" + # Prerelease version was already written to package.json + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc + npm --color="always" publish --tag next + fi + + if [ "$GITLAB_NPM_PUBLISH_NEXT" = "true" && "$GITLAB_NPM_PACKAGE_NAME" != "" ]; then + echo "Publishing $VERSION to GitLab" + node -e "fs.writeFileSync('package.json', JSON.stringify((json => {json.name = process.env.GITLAB_NPM_PACKAGE_NAME; json.publishConfig = {access: 'public'}; return json;})(JSON.parse(fs.readFileSync('package.json', 'utf-8'))), null, 4) + '\n', 'utf-8')" + node -e "fs.writeFileSync('package-lock.json', JSON.stringify((json => {json.name = process.env.GITLAB_NPM_PACKAGE_NAME; return json;})(JSON.parse(fs.readFileSync('package-lock.json', 'utf-8'))), null, 4) + '\n', 'utf-8')" + + echo "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}" | sed s/^https:// > .npmrc + npm --color="always" --registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/ publish --tag next + fi + + if [ "$GITHUB_NPM_PUBLISH_NEXT" = "true" && "$GITHUB_NPM_PACKAGE_NAME" != "" && "$GITHUB_REPOSITORY" != "" && "$GITHUB_TOKEN" != "" ]; then + echo "Publishing $VERSION to GitHub" + node -e "fs.writeFileSync('package.json', JSON.stringify((json => {json.name = process.env.GITHUB_NPM_PACKAGE_NAME; json.publishConfig = {access: 'public'}; json.repository = {type: 'git', url: 'https://github.com/' + process.env.GITHUB_REPOSITORY + '.git'}; return json;})(JSON.parse(fs.readFileSync('package.json', 'utf-8'))), null, 4) + '\n', 'utf-8')" + node -e "fs.writeFileSync('package-lock.json', JSON.stringify((json => {json.name = process.env.GITHUB_NPM_PACKAGE_NAME; return json;})(JSON.parse(fs.readFileSync('package-lock.json', 'utf-8'))), null, 4) + '\n', 'utf-8')" + + echo "//npm.pkg.github.com/:_authToken=${GITHUB_NPM_TOKEN}" > .npmrc + npm --color="always" --registry=https://npm.pkg.github.com/ publish --tag next + fi + fi artifacts: paths: - dist diff --git a/resources/build/ci-main-version.js b/resources/build/ci-main-version.js new file mode 100644 index 0000000..378838e --- /dev/null +++ b/resources/build/ci-main-version.js @@ -0,0 +1,60 @@ +import * as fs from 'node:fs/promises'; +import * as child_process from 'node:child_process'; +import * as util from 'node:util'; +import { fileURLToPath } from 'node:url'; + +const execFile = util.promisify(child_process.execFile); + +const options = {cwd: fileURLToPath(new URL('../..', import.meta.url))}; +const git = (...args) => execFile('git', args, options).then(({stdout}) => stdout.toString().trim()); + +const pkg = JSON.parse(await fs.readFile(new URL('../../package.json', import.meta.url), 'utf-8')); + +const [revision, branch_str, changed_files_str, tags_str, commit_count_str] = await Promise.all([ + git('rev-parse', 'HEAD'), + git('rev-parse', '--abbrev-ref', 'HEAD'), + git('diff', '--name-only', 'HEAD'), + git('log', '--tags', '--no-walk', '--pretty=%D'), + git('rev-list', '--count', 'HEAD'), +]); + +const branch = branch_str && branch_str !== 'HEAD' ? branch_str : null; +const changed_files = changed_files_str.length ? changed_files_str.split('\n') : []; +const tags = tags_str.split('\n').filter(t => t.startsWith('tag: ')).map(t => t.substr(5)); +const last_version = tags.find(t => t.startsWith('v'))?.substr(1) ?? null; +const commit_count = parseInt(commit_count_str); + +if (!last_version || pkg.version !== last_version) { + console.warn('Last tagged version does not match package.json version', { + version: pkg.version, + tag: last_version ? 'v' + last_version : null, + }); + process.exit(); +} + +const last_tagged_version_commit_count = parseInt(await git('rev-list', '--count', 'v' + last_version)); +const commit_count_since_last_version = commit_count - last_tagged_version_commit_count; + +if (commit_count_since_last_version <= 0) { + console.warn('No changes since last tagged version'); + process.exit(); +} + +const version = last_version + + '-next.' + (commit_count_since_last_version - 1) + + '+sha.' + revision.substr(0, 7); + +console.warn({ + version, + last_version, + revision, + branch, + changed_files, + tags, + last_version, + commit_count, + last_tagged_version_commit_count, + commit_count_since_last_version, +}); + +console.log(version); diff --git a/src/util/product.ts b/src/util/product.ts index 622de03..06f7146 100644 --- a/src/util/product.ts +++ b/src/util/product.ts @@ -6,7 +6,7 @@ import * as child_process from 'node:child_process'; import * as util from 'node:util'; import createDebug from 'debug'; -const exec = util.promisify(child_process.exec); +const execFile = util.promisify(child_process.execFile); const debug = createDebug('nxapi:util:product'); @@ -38,21 +38,24 @@ export const embedded_default_remote_config = globalThis.__NXAPI_BUNDLE_DEFAULT_ export const dir = path.resolve(fileURLToPath(import.meta.url), '..', '..', '..'); export const pkg = embedded_pkg ?? JSON.parse(await fs.readFile(path.join(dir, 'package.json'), 'utf-8')); -export const version: string = pkg.version; +const match = pkg.version.match(/^(\d+\.\d+\.\d+)-next\b/i); +export const version: string = match?.[1] ?? pkg.version; export const release: string | null = embedded_release ?? pkg.__nxapi_release ?? null; +const execGit = (...args: string[]) => execFile('git', args, {cwd: dir}).then(({stdout}) => stdout.toString().trim()); + export const git = typeof embedded_git !== 'undefined' ? embedded_git : await (async () => { try { await fs.stat(path.join(dir, '.git')); } catch (err) { + if (!release) debug('Unable to find revision'); return null; } - const options: child_process.ExecOptions = {cwd: dir}; const [revision, branch, changed_files] = await Promise.all([ - exec('git rev-parse HEAD', options).then(({stdout}) => stdout.toString().trim()), - exec('git rev-parse --abbrev-ref HEAD', options).then(({stdout}) => stdout.toString().trim()), - exec('git diff --name-only HEAD', options).then(({stdout}) => stdout.toString().trim()), + execGit('rev-parse', 'HEAD'), + execGit('rev-parse', '--abbrev-ref', 'HEAD'), + execGit('diff', '--name-only', 'HEAD'), ]); return { @@ -66,4 +69,5 @@ export const dev = process.env.NODE_ENV !== 'production' && (!!git || process.env.NODE_ENV === 'development'); export const product = 'nxapi ' + version + - (!release && git ? '-' + git.revision.substr(0, 7) + (git.branch ? ' (' + git.branch + ')' : '') : ''); + (!release && git ? '-' + git.revision.substr(0, 7) + (git.branch ? ' (' + git.branch + ')' : '') : + !release ? '-?' : ''); diff --git a/src/util/useragent.ts b/src/util/useragent.ts index bc644ac..190f707 100644 --- a/src/util/useragent.ts +++ b/src/util/useragent.ts @@ -3,7 +3,8 @@ import * as os from 'node:os'; import { git, release, version } from '../util/product.js'; const default_useragent = 'nxapi/' + version + ' (' + - (!release && git ? 'git ' + git.revision.substr(0, 7) + (git.branch ? ' ' + git.branch : '') + '; ' : '') + + (!release && git ? 'git ' + git.revision.substr(0, 7) + (git.branch ? ' ' + git.branch : '') + '; ' : + !release ? 'no-git; ' : '') + 'node ' + process.versions.node + '; ' + process.platform + ' ' + os.release() + ')'; diff --git a/tsconfig.json b/tsconfig.json index c583234..a85f095 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,10 +19,7 @@ "skipLibCheck": true, "allowJs": true }, - "exclude": [ - "dist", - "bin", - "rollup.config.js", - "data" + "include": [ + "src" ] }