diff --git a/.changeset/fast-drinks-build.md b/.changeset/fast-drinks-build.md new file mode 100644 index 0000000..ddd0775 --- /dev/null +++ b/.changeset/fast-drinks-build.md @@ -0,0 +1,5 @@ +--- +"@adobe/aio-lib-telemetry": patch +--- + +Fixes the `export` paths for ESM which were pointing to wrong files diff --git a/.github/workflows/deprecate.yml b/.github/workflows/deprecate.yml new file mode 100644 index 0000000..20bf871 --- /dev/null +++ b/.github/workflows/deprecate.yml @@ -0,0 +1,132 @@ +name: Deprecate Package + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to deprecate (e.g., 1.0.0 or @adobe/aio-lib-telemetry@1.0.0)' + required: true + type: string + + message: + description: 'Deprecation message' + required: true + type: string + default: 'This version has been deprecated. Please upgrade to the latest version.' + + unpublish: + description: 'Also unpublish the version (WARNING: Irreversible and discouraged by npm)' + required: false + type: boolean + default: false + + dry_run: + description: 'Dry run (simulate without making actual changes)' + required: false + type: boolean + default: false + +jobs: + deprecate: + name: Deprecate Package Version + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + registry-url: 'https://registry.npmjs.org' + + - name: Validate and normalize version + id: version + run: | + echo "Version input: ${{ inputs.version }}" + echo "Message: ${{ inputs.message }}" + echo "Also unpublish: ${{ inputs.unpublish }}" + echo "Dry run: ${{ inputs.dry_run }}" + + VERSION="${{ inputs.version }}" + + # Validate version format (major.minor.patch only) + # Regex source: Simplified semantic versioning pattern matching X.Y.Z format + # Reference: https://semver.org/ (basic version core: MAJOR.MINOR.PATCH) + if [[ "$VERSION" =~ ^(@[a-z0-9-]+/[a-z0-9-]+@)?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # Valid format + if [[ "$VERSION" =~ ^@.+/.+@ ]]; then + # Already has package name + VALIDATED_VERSION="$VERSION" + else + # Add package name + VALIDATED_VERSION="@adobe/aio-lib-telemetry@$VERSION" + fi + else + echo "::error::Invalid version format. Expected: 'X.Y.Z' (e.g., '1.0.0') or '@adobe/aio-lib-telemetry@X.Y.Z'" + echo "::error::Pre-release versions and build metadata are not supported." + exit 1 + fi + + echo "Validated version: $VALIDATED_VERSION" + echo "VALIDATED_VERSION=$VALIDATED_VERSION" >> "$GITHUB_OUTPUT" + + - name: Deprecate package version + run: | + VERSION="${{ steps.version.outputs.VALIDATED_VERSION }}" + + if [[ "${{ inputs.dry_run }}" == "true" ]]; then + echo "🔍 DRY RUN: Would deprecate: $VERSION" + echo "🔍 DRY RUN: With message: ${{ inputs.message }}" + else + echo "Deprecating: $VERSION" + npm deprecate "$VERSION" "${{ inputs.message }}" + fi + env: + NODE_AUTH_TOKEN: ${{ secrets.ADOBE_BOT_NPM_TOKEN }} + + - name: Unpublish package version + if: ${{ inputs.unpublish }} + run: | + VERSION="${{ steps.version.outputs.VALIDATED_VERSION }}" + + if [[ "${{ inputs.dry_run }}" == "true" ]]; then + echo "🔍 DRY RUN: Would unpublish: $VERSION" + echo "⚠️ WARNING: This action would be irreversible and is discouraged by npm." + echo "This action is irreversible and discouraged by npm." + echo "Consider using deprecate instead." + else + echo "Unpublishing: $VERSION" + npm unpublish "$VERSION" + fi + env: + NODE_AUTH_TOKEN: ${{ secrets.ADOBE_BOT_NPM_TOKEN }} + + - name: Verify action + run: | + VERSION="${{ steps.version.outputs.VALIDATED_VERSION }}" + + # Extract just the version number + VERSION_NUM="${VERSION##*@}" + + if [[ "${{ inputs.dry_run }}" == "true" ]]; then + echo "🔍 DRY RUN completed successfully - no actual changes were made" + echo "Would have deprecated version $VERSION_NUM" + echo "📝 With message: ${{ inputs.message }}" + + if [[ "${{ inputs.unpublish }}" == "true" ]]; then + echo "Would have also unpublished version $VERSION_NUM" + fi + else + echo "Action completed successfully" + echo "✅ Version $VERSION_NUM has been deprecated" + echo "📝 Message: ${{ inputs.message }}" + + if [[ "${{ inputs.unpublish }}" == "true" ]]; then + echo "✅ Version $VERSION_NUM has also been unpublished" + fi + fi + diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 9eb488c..5f6eec1 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -30,8 +30,8 @@ jobs: - name: Run Knip run: npx knip - code-quality: - name: Check Code Quality (Node ${{ matrix.node-version }}) + check-build-test: + name: Check, Build, Test, and Publint (Node ${{ matrix.node-version }}) runs-on: ubuntu-latest strategy: # We want to run checks on all versions, even if some fail. @@ -56,46 +56,11 @@ jobs: - name: Check types run: npm run typecheck - build: - name: Build (Node ${{ matrix.node-version }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - # Previous LTS (Maintenance), Current LTS, Latest stable - node-version: [20, 22, 24] - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup environment - uses: ./.github/actions/setup-ci-env - with: - install-deps: true - node-version: ${{ matrix.node-version }} - - name: Run Build run: npm run build - test: - name: Test (Node ${{ matrix.node-version }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - # Previous LTS (Maintenance), Current LTS, Latest stable - node-version: [20, 22, 24] - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup environment - uses: ./.github/actions/setup-ci-env - with: - install-deps: true - node-version: ${{ matrix.node-version }} - - name: Run Tests run: npm run test + + - name: Run Publint + run: npm run publint diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e742df0..27ec021 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -44,19 +44,19 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.ADOBE_BOT_NPM_TOKEN }} - - name: Generate Slack Announcement - id: announcement - if: steps.changesets.outputs.published == 'true' - run: | - # From Node v22.18.0, the node command is able to run .ts files directly (if it only needs type stripping). - # As of August 2025, Node v22.18.0 is already LTS (the version used by this workflow). - SLACK_WEBHOOK_PAYLOAD="$(node .github/scripts/announce.ts '${{ steps.changesets.outputs.publishedPackages }}')" - echo "SLACK_WEBHOOK_PAYLOAD=$SLACK_WEBHOOK_PAYLOAD" >> "$GITHUB_OUTPUT" + # - name: Generate Slack Announcement + # id: announcement + # if: steps.changesets.outputs.published == 'true' + # run: | + # # From Node v22.18.0, the node command is able to run .ts files directly (if it only needs type stripping). + # # As of August 2025, Node v22.18.0 is already LTS (the version used by this workflow). + # SLACK_WEBHOOK_PAYLOAD="$(node .github/scripts/announce.ts '${{ steps.changesets.outputs.publishedPackages }}')" + # echo "SLACK_WEBHOOK_PAYLOAD=$SLACK_WEBHOOK_PAYLOAD" >> "$GITHUB_OUTPUT" - - name: Notify on Slack - uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 - if: steps.changesets.outputs.published == 'true' - with: - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: incoming-webhook - payload: ${{ steps.announcement.outputs.SLACK_WEBHOOK_PAYLOAD }} + # - name: Notify on Slack + # uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + # if: steps.changesets.outputs.published == 'true' + # with: + # webhook: ${{ secrets.SLACK_WEBHOOK_URL }} + # webhook-type: incoming-webhook + # payload: ${{ steps.announcement.outputs.SLACK_WEBHOOK_PAYLOAD }} diff --git a/knip.json b/knip.json index d3e5fc3..df62b3f 100644 --- a/knip.json +++ b/knip.json @@ -1,3 +1,3 @@ { - "project": ["**/*", "!docs"] + "project": ["**/*", "!docs", "!.github/scripts"] } diff --git a/package-lock.json b/package-lock.json index 8d35fe3..be2f83c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@adobe/aio-lib-telemetry", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@adobe/aio-lib-telemetry", - "version": "1.1.0", + "version": "1.1.1", "license": "Apache-2.0", "dependencies": { "@adobe/aio-lib-core-logging": "^3.0.2", @@ -52,6 +52,7 @@ "knip": "^5.61.3", "lint-staged": "^16.2.7", "prettier": "^3.6.2", + "publint": "^0.3.15", "tsdown": "^0.16.0", "typedoc": "^0.28.5", "typedoc-plugin-markdown": "^4.6.3", @@ -3204,6 +3205,19 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "license": "BSD-3-Clause" }, + "node_modules/@publint/pack": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@publint/pack/-/pack-0.1.2.tgz", + "integrity": "sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://bjornlu.com/sponsor" + } + }, "node_modules/@quansync/fs": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-0.1.5.tgz", @@ -6552,6 +6566,36 @@ "node": ">=12.0.0" } }, + "node_modules/publint": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.15.tgz", + "integrity": "sha512-xPbRAPW+vqdiaKy5sVVY0uFAu3LaviaPO3pZ9FaRx59l9+U/RKR1OEbLhkug87cwiVKxPXyB4txsv5cad67u+A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@publint/pack": "^0.1.2", + "package-manager-detector": "^1.3.0", + "picocolors": "^1.1.1", + "sade": "^1.8.1" + }, + "bin": { + "publint": "src/cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://bjornlu.com/sponsor" + } + }, + "node_modules/publint/node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "dev": true, + "license": "MIT" + }, "node_modules/punycode.js": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", @@ -6866,6 +6910,19 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/package.json b/package.json index 7a79853..e257ddc 100644 --- a/package.json +++ b/package.json @@ -21,24 +21,39 @@ "engines": { "node": ">=20 <=24" }, - "main": "./dist/cjs/index.cjs", - "module": "./dist/es/index.js", - "types": "./dist/cjs/index.d.cts", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.cts", "exports": { ".": { - "types": "./dist/cjs/index.d.cts", - "import": "./dist/es/index.js", - "require": "./dist/cjs/index.cjs" + "import": { + "types": "./dist/index.d.mts", + "import": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "import": "./dist/index.cjs" + } }, "./otel": { - "types": "./dist/cjs/otel.d.cts", - "import": "./dist/es/otel.js", - "require": "./dist/cjs/otel.cjs" + "import": { + "types": "./dist/otel.d.mts", + "import": "./dist/otel.mjs" + }, + "require": { + "types": "./dist/otel.d.cts", + "import": "./dist/otel.cjs" + } }, "./integrations": { - "types": "./dist/integrations.d.cts", - "import": "./dist/es/integrations/index.js", - "require": "./dist/cjs/integrations/index.cjs" + "import": { + "types": "./dist/integrations/index.d.mts", + "import": "./dist/integrations/index.mjs" + }, + "require": { + "types": "./dist/integrations/index.d.cts", + "import": "./dist/integrations/index.cjs" + } }, "./package.json": "./package.json" }, @@ -51,6 +66,7 @@ "assist": "biome check --formatter-enabled=false --linter-enabled=false --assist-enabled=true --no-errors-on-unmatched", "assist:apply": "biome check --write --formatter-enabled=false --linter-enabled=false --assist-enabled=true --no-errors-on-unmatched", "build": "tsdown", + "publint": "publint", "changeset": "changeset", "check:ci": "biome ci --formatter-enabled=true --linter-enabled=true --assist-enabled=true --no-errors-on-unmatched", "docs": "typedoc", @@ -111,6 +127,7 @@ "knip": "^5.61.3", "lint-staged": "^16.2.7", "prettier": "^3.6.2", + "publint": "^0.3.15", "tsdown": "^0.16.0", "typedoc": "^0.28.5", "typedoc-plugin-markdown": "^4.6.3", diff --git a/tsdown.config.ts b/tsdown.config.ts index 4571143..91b038d 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -10,8 +10,6 @@ * governing permissions and limitations under the License. */ -import { readdir, rename } from "node:fs/promises"; - import { defineConfig } from "tsdown"; const OUT_DIR = "./dist"; @@ -57,29 +55,4 @@ export default defineConfig({ js: ADOBE_LICENSE_BANNER, dts: ADOBE_LICENSE_BANNER, }, - - hooks: { - "build:before": (ctx) => { - if (ctx.buildOptions.output) { - // Move each output into its own directory. - const { format } = ctx.buildOptions.output; - ctx.buildOptions.output.dir += `/${format}`; - } - }, - - "build:done": async (_) => { - // For some reason the types for CJS are being placed out of the CJS directory. - // This is a workaround to move them into the CJS directory. - const files = await readdir(OUT_DIR); - const ctsFiles = files.filter((file) => file.endsWith(".d.cts")); - - const renamePromises = ctsFiles.map((file) => { - const sourcePath = `${OUT_DIR}/${file}`; - const targetPath = `${OUT_DIR}/cjs/${file}`; - return rename(sourcePath, targetPath); - }); - - await Promise.all(renamePromises); - }, - }, });