diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 50caeee..57b8177 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -91,4 +91,4 @@ jobs: path: sdk-package - name: Publish to NPM - run: bash ./bin/publish-npm sdk-package/*.tgz + run: bash ./bin/publish-npm ./sdk-package/*.tgz diff --git a/bin/publish-npm b/bin/publish-npm index 65580ef..e28e7ed 100644 --- a/bin/publish-npm +++ b/bin/publish-npm @@ -12,12 +12,18 @@ if [ "$#" -ne 1 ]; then exit 1 fi -ARCHIVE="$1" -if [ ! -f "$ARCHIVE" ]; then - echo "verified package archive not found: $ARCHIVE" >&2 +ARCHIVE_INPUT="$1" +if [ ! -f "$ARCHIVE_INPUT" ]; then + echo "verified package archive not found: $ARCHIVE_INPUT" >&2 exit 1 fi +# npm treats a relative path without a leading ./ as a package spec. Resolve the +# verified archive to an absolute path so workflow paths such as +# sdk-package/unlayer-sdk-0.2.0.tgz are always published as local files. +ARCHIVE_DIRECTORY="$(cd "$(dirname "$ARCHIVE_INPUT")" && pwd -P)" +ARCHIVE="$ARCHIVE_DIRECTORY/$(basename "$ARCHIVE_INPUT")" + # Read release identity from the exact archive that passed verification. PACKAGE_JSON="$(tar -xOf "$ARCHIVE" package/package.json)" PACKAGE_NAME="$(echo "$PACKAGE_JSON" | jq -r -e '.name')" diff --git a/tests/publish-npm.test.mjs b/tests/publish-npm.test.mjs index 1a5fbd6..56f1283 100644 --- a/tests/publish-npm.test.mjs +++ b/tests/publish-npm.test.mjs @@ -84,8 +84,8 @@ esac ); fs.chmodSync(fakeNpm, 0o755); - const run = (mode, { lastVersion = earlierRegistryVersion } = {}) => - spawnSync('bash', ['./bin/publish-npm', archive], { + const run = (mode, { archiveArgument = archive, lastVersion = earlierRegistryVersion } = {}) => + spawnSync('bash', ['./bin/publish-npm', archiveArgument], { cwd: repositoryRoot, encoding: 'utf8', env: { @@ -118,7 +118,7 @@ for (const mode of ['success', 'e404']) { assert.equal(result.status, 0, result.stderr); assert.equal( fs.readFileSync(harness.publishLog, 'utf8').trim(), - `publish ${harness.archive} --tag latest --access public`, + `publish ${fs.realpathSync(harness.archive)} --tag latest --access public`, ); } finally { harness.cleanup(); @@ -126,6 +126,29 @@ for (const mode of ['success', 'e404']) { }); } +test('publishes a workflow-style relative archive path as a local file', () => { + const harness = createHarness(); + const relativeDirectory = fs.mkdtempSync(path.join(repositoryRoot, 'sdk-package-test.')); + const relativeArchive = path.join(relativeDirectory, path.basename(harness.archive)); + fs.copyFileSync(harness.archive, relativeArchive); + + try { + const archiveArgument = path.relative(repositoryRoot, relativeArchive); + assert.equal(path.isAbsolute(archiveArgument), false); + assert.equal(archiveArgument.startsWith('.'), false); + + const result = harness.run('e404', { archiveArgument }); + assert.equal(result.status, 0, result.stderr); + assert.equal( + fs.readFileSync(harness.publishLog, 'utf8').trim(), + `publish ${fs.realpathSync(relativeArchive)} --tag latest --access public`, + ); + } finally { + fs.rmSync(relativeDirectory, { force: true, recursive: true }); + harness.cleanup(); + } +}); + test('does not move latest backwards when an older stable release is dispatched', () => { const harness = createHarness(); try {