diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e5b6d8d6..00000000 --- a/.changeset/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index 0ad25f43..00000000 --- a/.changeset/config.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@1.6.3/schema.json", - "changelog": [ - "@changesets/changelog-github", - { "repo": "twodft/astro-icon" } - ], - "commit": false, - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": ["www", "service", "demo"] -} diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json new file mode 100644 index 00000000..b8f99a37 --- /dev/null +++ b/.github/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + "packages/core": "1.3.3" +} diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 00000000..52b73b04 --- /dev/null +++ b/.github/release-please-config.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "node", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "pull-request-title-pattern": "chore: release${component} ${version}", + "changelog-sections": [ + { "type": "feat", "section": "Features" }, + { "type": "fix", "section": "Bug Fixes" }, + { "type": "perf", "section": "Performance Improvements" }, + { "type": "deps", "section": "Dependencies" }, + { "type": "revert", "section": "Reverts" }, + { "type": "docs", "section": "Documentation", "hidden": false }, + { "type": "chore", "section": "Miscellaneous", "hidden": true }, + { "type": "refactor", "section": "Miscellaneous", "hidden": true }, + { "type": "test", "section": "Miscellaneous", "hidden": true }, + { "type": "build", "section": "Miscellaneous", "hidden": true }, + { "type": "ci", "section": "Miscellaneous", "hidden": true } + ], + "packages": { + "packages/core": { + "component": "@dallay/astro-icon", + "release-type": "node", + "package-name": "@dallay/astro-icon", + "changelog-path": "CHANGELOG.md", + "tag-name": "v${version}", + "release-as": "" + } + } +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e16da551..f93d5bed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,42 +21,64 @@ jobs: lint: name: Lint runs-on: ubuntu-latest + permissions: + contents: write steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 cache: 'pnpm' - run: pnpm install - # Lint autofix cannot run on forks, so just skip those! See https://github.com/wearerequired/lint-action/issues/13 - - name: Lint (External) - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.owner.login != github.repository_owner }} + # Check only — forks and Dependabot (no write access to push fixes) + - name: Lint (check only — forks and Dependabot) + if: | + (github.event_name == 'pull_request' && github.event.pull_request.head.repo.owner.login != github.repository_owner) || + contains(github.actor, 'dependabot') run: pnpm run lint - - # Otherwise, run lint autofixer - - name: Lint - if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }} - uses: wearerequired/lint-action@v2 + + # Auto-fix + commit — push to main or human PRs from same repo + - name: Lint (auto-fix) + if: | + !contains(github.actor, 'dependabot') && + (github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner) + run: pnpm run lint:fix || true + + - name: Commit lint fixes + if: | + !contains(github.actor, 'dependabot') && + (github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner) env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - prettier: true - auto_fix: true - git_name: github-actions[bot] - git_email: github-actions[bot]@users.noreply.github.com - commit_message: 'chore(lint): ${linter} fix' - github_token: ${{ secrets.GITHUB_TOKEN }} - neutral_check_on_warning: true + HEAD_REF: ${{ github.head_ref }} + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if git diff --quiet; then + echo "No lint fixes needed." + exit 0 + fi + git add -A + git commit -m "chore(lint): biome auto-fix" + # actions/checkout leaves a detached HEAD on PR events. + # Push back to the source branch explicitly; --force-with-lease + # prevents overwriting concurrent pushes that aren't ours. + if [ -n "$HEAD_REF" ]; then + git push origin "HEAD:${HEAD_REF}" --force-with-lease + else + git push + fi smoke: name: Smoke Test runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 cache: 'pnpm' diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 00000000..2e88cbfa --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,159 @@ +name: Release Please + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +defaults: + run: + shell: bash + +jobs: + release-please: + name: Release Please + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + pull-requests: write + outputs: + release_created: ${{ steps.release.outputs.releases_created }} + tag_name: ${{ steps.release.outputs['packages/core--tag_name'] }} + version: ${{ steps.release.outputs['packages/core--version'] }} + steps: + - name: Generate GitHub App Token + id: app-token + uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Run Release Please + id: release + uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 + with: + token: ${{ steps.app-token.outputs.token }} + config-file: .github/release-please-config.json + manifest-file: .github/.release-please-manifest.json + + publish: + name: Publish to npm + runs-on: ubuntu-latest + timeout-minutes: 15 + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + environment: npm + permissions: + contents: read + id-token: write + steps: + - name: Generate GitHub App Token + id: app-token + uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + token: ${{ steps.app-token.outputs.token }} + ref: ${{ needs.release-please.outputs.tag_name }} + + - name: Setup pnpm + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.1.0 + + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build package + run: pnpm --filter @dallay/astro-icon run build + + - name: Publish to npm + working-directory: packages/core + run: pnpm publish --access public --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + deploy-www: + name: Deploy www to Vercel + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + steps: + - name: Trigger Vercel deploy hook + run: curl -s -X POST "${{ secrets.VERCEL_DEPLOY_HOOK_WWW }}" + + deploy-service: + name: Deploy service to Vercel + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + steps: + - name: Trigger Vercel deploy hook + run: curl -s -X POST "${{ secrets.VERCEL_DEPLOY_HOOK_SERVICE }}" + + deploy-demo: + name: Deploy demo to Cloudflare Pages + runs-on: ubuntu-latest + timeout-minutes: 15 + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + permissions: + contents: read + steps: + - name: Generate GitHub App Token + id: app-token + uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + token: ${{ steps.app-token.outputs.token }} + ref: ${{ needs.release-please.outputs.tag_name }} + + - name: Setup pnpm + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.1.0 + + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build core and demo + run: | + pnpm --filter @dallay/astro-icon run build + pnpm --filter demo run build + + - name: Deploy to Cloudflare Pages + uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3.14.1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: a6500bbcdec00bf4c9fc57052081baa7 + command: pages deploy dist --project-name=astro-icon-demo --branch=main + workingDirectory: demo diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f70358a6..9b8b3053 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,17 +1,22 @@ -name: Release +name: Release (Manual) + +# Manual fallback publish — use only for emergency hotfixes. +# Normal releases are handled automatically by the release-please.yml workflow. on: - push: - tags: - - "v*.*.*" workflow_dispatch: + inputs: + confirm: + description: 'Type "publish" to confirm manual release' + required: true + type: string env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: false defaults: run: @@ -19,28 +24,37 @@ defaults: jobs: publish: - name: Publish npm package + name: Publish npm package (manual) runs-on: ubuntu-latest timeout-minutes: 15 + if: inputs.confirm == 'publish' environment: npm permissions: contents: read id-token: write steps: + - name: Generate GitHub App Token + id: app-token + uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: + token: ${{ steps.app-token.outputs.token }} fetch-depth: 0 - name: Setup pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.1.0 - name: Setup Node.js - uses: actions/setup-node@v6 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.14.0 - registry-url: "https://registry.npmjs.org" - cache: "pnpm" + node-version: 22 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile @@ -50,21 +64,18 @@ jobs: npm install --global npm@^11.5.1 npm --version - - name: Verify tag matches package version - if: startsWith(github.ref, 'refs/tags/v') + - name: Verify branch is main run: | - TAG_VERSION="${GITHUB_REF_NAME#v}" - PACKAGE_VERSION="$(node -p "require('./packages/core/package.json').version")" - - if [[ "$TAG_VERSION" != "$PACKAGE_VERSION" ]]; then - echo "Tag version ($TAG_VERSION) does not match packages/core/package.json ($PACKAGE_VERSION)." + if [[ "${{ github.ref }}" != "refs/heads/main" ]]; then + echo "Manual publish must run from main branch, got: ${{ github.ref }}" exit 1 fi - name: Build package - run: pnpm --filter @twodft/astro-icon run build + run: pnpm --filter @dallay/astro-icon run build - name: Publish package - if: startsWith(github.ref, 'refs/tags/v') working-directory: packages/core run: pnpm publish --access public --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.nvmrc b/.nvmrc index dc0bb0f4..5bf4400f 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v22.12.0 +24.15.0 diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..034e8480 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 5.1.x | :white_check_mark: | +| 5.0.x | :x: | +| 4.0.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +Use this section to tell people how to report a vulnerability. + +Tell them where to go, how often they can expect to get an update on a +reported vulnerability, what to expect if the vulnerability is accepted or +declined, etc. diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..8812016a --- /dev/null +++ b/biome.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "includes": ["**", "!**/dist", "!**/node_modules", "!pnpm-lock.yaml"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 100 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double", + "trailingCommas": "all", + "semicolons": "always" + } + }, + "json": { + "formatter": { + "enabled": true + } + } +} diff --git a/demo/astro.config.ts b/demo/astro.config.ts index a0c95e92..31d512bf 100644 --- a/demo/astro.config.ts +++ b/demo/astro.config.ts @@ -1,6 +1,6 @@ -import { defineConfig } from "astro/config"; import cloudflare from "@astrojs/cloudflare"; -import icon from "@twodft/astro-icon"; +import icon from "@dallay/astro-icon"; +import { defineConfig } from "astro/config"; // https://astro.build/config export default defineConfig({ diff --git a/demo/package.json b/demo/package.json index b270d795..ab0653e0 100644 --- a/demo/package.json +++ b/demo/package.json @@ -15,8 +15,9 @@ "@iconify-json/ri": "^1.2.10" }, "devDependencies": { - "@astrojs/cloudflare": "^13.1.8", - "@twodft/astro-icon": "workspace:*", - "astro": "^6.1.4" + "@astrojs/cloudflare": "^13.5.1", + "@dallay/astro-icon": "workspace:*", + "astro": "^6.3.3", + "wrangler": "^4.92.0" } } diff --git a/demo/src/layouts/base.astro b/demo/src/layouts/base.astro index 96d2b4c6..c51fe161 100644 --- a/demo/src/layouts/base.astro +++ b/demo/src/layouts/base.astro @@ -3,10 +3,40 @@ +