diff --git a/.github/workflows/build-gems.yml b/.github/workflows/build-gems.yml index 41d0b1c69..e134f1efb 100644 --- a/.github/workflows/build-gems.yml +++ b/.github/workflows/build-gems.yml @@ -7,7 +7,6 @@ on: push: branches: [main] - tags: ["v*"] paths: - "src/**" - "lib/**" @@ -17,6 +16,7 @@ on: - "Makefile" - "Rakefile" - ".ruby-version" + - "config.yml" pull_request: paths: @@ -28,6 +28,7 @@ on: - "Makefile" - "Rakefile" - ".ruby-version" + - "config.yml" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -110,21 +111,6 @@ jobs: permissions: contents: write id-token: write - strategy: - fail-fast: false - matrix: - target: - - default - - aarch64-linux-gnu - - x86_64-linux-gnu - - x86_64-linux-musl - - aarch64-linux-musl - - x86_64-darwin - - arm64-darwin - - arm-linux-gnu - - arm-linux-musl - - x86-linux-gnu - - x86-linux-musl steps: - uses: actions/checkout@v4 with: @@ -147,8 +133,9 @@ jobs: - name: Download gem artifacts uses: actions/download-artifact@v4 with: - name: gem-${{ matrix.target }} + pattern: gem-* path: pkg/ + merge-multiple: true - name: Configure trusted publishing credentials uses: rubygems/configure-rubygems-credentials@v1.0.0 diff --git a/.github/workflows/javascript.yml b/.github/workflows/javascript.yml index fa85388b2..b63a51d5c 100644 --- a/.github/workflows/javascript.yml +++ b/.github/workflows/javascript.yml @@ -5,6 +5,10 @@ on: branches: - main pull_request: + pull_request_review: + types: [submitted] + release: + types: [published] permissions: actions: read @@ -59,14 +63,26 @@ jobs: run: yarn playwright install - name: Build tailwind-class-sorter package + env: + RELEASE_BUILD: ${{ github.event_name == 'release' && 'true' || 'false' }} run: yarn nx build @herb-tools/tailwind-class-sorter - name: Run `build` for all NX packages + env: + RELEASE_BUILD: ${{ github.event_name == 'release' && 'true' || 'false' }} run: yarn build - name: Run `test` for all NX packages run: yarn test + - name: Upload package artifacts + uses: actions/upload-artifact@v4 + with: + name: npm-packages + path: javascript/packages/*/ + if-no-files-found: error + retention-days: 1 + # NX is not able to properly detect affected changes if things change in C source or the WASM build # # - name: Set NX SHAs @@ -75,3 +91,115 @@ jobs: # # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected # - run: npx nx affected -t build # - run: npx nx affected -t test + + publish: + name: Publish packages to npm + if: github.event_name == 'release' && github.repository_owner == 'marcoroth' + needs: main + runs-on: ubuntu-latest + timeout-minutes: 30 + + permissions: + contents: read + id-token: write + + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + + - name: Download package artifacts + uses: actions/download-artifact@v4 + with: + name: npm-packages + path: javascript/packages/ + + - name: Publish packages with provenance + run: | + for package_dir in javascript/packages/*; do + if [ -d "$package_dir" ] && [ -f "$package_dir/package.json" ]; then + package=$(basename "$package_dir") + + if [ "$package" = "vscode" ]; then + echo "Skipping vscode package..." + continue + fi + + echo "Publishing $package..." + (cd "$package_dir" && npm publish --provenance --access public) + fi + done + + preview-check: + if: | + (github.repository == 'marcoroth/herb' && github.event_name == 'pull_request' && github.event.pull_request.user.login == github.repository_owner) || + (github.repository == 'marcoroth/herb' && github.event_name == 'pull_request_review' && github.event.review.state == 'approved') + + runs-on: ubuntu-latest + outputs: + has-permissions: ${{ steps.check.outputs.require-result }} + + steps: + - name: Check permissions + id: check + uses: actions-cool/check-user-permission@v2 + with: + require: write + + preview: + name: Publish preview packages + needs: [main, preview-check] + if: needs.preview-check.outputs.has-permissions == 'true' + runs-on: ubuntu-latest + + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Download package artifacts + uses: actions/download-artifact@v4 + with: + name: npm-packages + path: javascript/packages/ + + - name: Publish preview packages + run: npx pkg-pr-new publish --compact --comment=update --bin --no-template './javascript/packages/formatter' './javascript/packages/linter' './javascript/packages/language-server' + + publish-vscode: + name: Publish VSCode extension + if: github.event_name == 'release' && github.repository_owner == 'marcoroth' + needs: main + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Download package artifacts + uses: actions/download-artifact@v4 + with: + name: npm-packages + path: javascript/packages/ + + - name: Publish to VS Code Marketplace + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + run: | + cd javascript/packages/vscode + npx @vscode/vsce publish + + - name: Publish to Open VSX Registry + env: + OVSX_PAT: ${{ secrets.OVSX_PAT }} + run: | + cd javascript/packages/vscode + npx ovsx publish -p $OVSX_PAT diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 52c7b70fa..4001a22eb 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -5,6 +5,8 @@ on: branches: - main pull_request: + release: + types: [published] permissions: actions: read @@ -74,3 +76,43 @@ jobs: - name: Test cargo package run: cargo package --allow-dirty working-directory: rust + + - name: Upload Rust artifacts + if: github.event_name == 'release' + uses: actions/upload-artifact@v4 + with: + name: rust-package + path: rust/ + if-no-files-found: error + retention-days: 1 + + publish: + name: Publish to crates.io + if: github.event_name == 'release' && github.repository_owner == 'marcoroth' + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + id-token: write + steps: + - name: Download Rust artifacts + uses: actions/download-artifact@v4 + with: + name: rust-package + path: rust/ + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Authenticate with crates.io + uses: rust-lang/crates-io-auth-action@v1 + id: auth + + - name: Publish to crates.io + env: + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} + run: cargo publish --allow-dirty + working-directory: rust diff --git a/README.md b/README.md index b11b7bcf5..07d95bd4c 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,13 @@

Gem Version + Crates.io Version + npm Version + VS Code Marketplace + Open VSX Documentation playground + pkg.pr.new License Issues

@@ -99,7 +104,7 @@ Commands: bundle exec herb version Prints the versions of the Herb gem and the libherb library. ``` -For detailed information, like how you can use Herb programatically in Ruby and JavaScript, visit the [documentation site](https://herb-tools.dev/bindings/ruby/reference). +For detailed information, like how you can use Herb programmatically in Ruby and JavaScript, visit the [documentation site](https://herb-tools.dev/bindings/ruby/reference). ## Background and Talk diff --git a/docs/docs/bindings/javascript/index.md b/docs/docs/bindings/javascript/index.md index 6600c45ad..690fec14a 100644 --- a/docs/docs/bindings/javascript/index.md +++ b/docs/docs/bindings/javascript/index.md @@ -111,6 +111,50 @@ Herb.load().then(() => { You are now ready to parse HTML+ERB in Node.js. +## Using Unreleased Commits + +Each commit on the `main` branch and pull requests with approved reviews are published to [pkg.pr.new](https://pkg.pr.new/~/marcoroth/herb). You can install preview packages directly from commits or PRs: + +:::code-group +```shell [npm] +npm i https://pkg.pr.new/@herb-tools/core@{commit} +``` + +```shell [pnpm] +pnpm add https://pkg.pr.new/@herb-tools/core@{commit} +``` + +```shell [yarn] +yarn add https://pkg.pr.new/@herb-tools/core@{commit} +``` + +```shell [bun] +bun add https://pkg.pr.new/@herb-tools/core@{commit} +``` +::: + +Replace `{commit}` with the short commit SHA (e.g., `0d2eabe`) or branch name (e.g., `main`). + +### Running CLI Tools from Previews + +You can also run CLI tools directly from preview releases without installing: + +:::code-group +```shell [Linter] +npx https://pkg.pr.new/@herb-tools/linter@{commit} template.html.erb +``` + +```shell [Formatter] +npx https://pkg.pr.new/@herb-tools/formatter@{commit} template.html.erb +``` + +```shell [Language Server] +npx https://pkg.pr.new/@herb-tools/language-server@{commit} --stdio +``` +::: + +This is perfect for testing bug fixes or new features before they're officially released! + ## Getting Started Regardless of whether you imported `Herb` from `@herb-tools/browser` or `@herb-tools/node`, the API remains the same for both packages. diff --git a/docs/docs/overview.md b/docs/docs/overview.md index 38ec53de5..8eb496fbe 100644 --- a/docs/docs/overview.md +++ b/docs/docs/overview.md @@ -8,4 +8,4 @@ title: Getting Started

Herb

- + diff --git a/javascript/packages/formatter/README.md b/javascript/packages/formatter/README.md index 6d187ae47..8bcda4789 100644 --- a/javascript/packages/formatter/README.md +++ b/javascript/packages/formatter/README.md @@ -42,6 +42,16 @@ For occasional use without installing: npx @herb-tools/formatter template.html.erb ``` +### Preview Releases + +Want to try unreleased features? Use pkg.pr.new to run the formatter from any commit or PR: + +```bash +npx https://pkg.pr.new/@herb-tools/formatter@{commit} template.html.erb +``` + +Replace `{commit}` with a commit SHA (e.g., `0d2eabe`) or branch name (e.g., `main`). Find available previews at [pkg.pr.new/~/marcoroth/herb](https://pkg.pr.new/~/marcoroth/herb). + ### Project Installation :::code-group diff --git a/javascript/packages/language-server/README.md b/javascript/packages/language-server/README.md index 141e4ee03..34f1fe6bc 100644 --- a/javascript/packages/language-server/README.md +++ b/javascript/packages/language-server/README.md @@ -81,6 +81,16 @@ npm install -g @herb-tools/language-server yarn global add @herb-tools/language-server ``` +##### Preview Releases + +Want to try unreleased features? Use pkg.pr.new to run the language server from any commit or PR: + +```bash +npx https://pkg.pr.new/@herb-tools/language-server@{commit} --stdio +``` + +Replace `{commit}` with a commit SHA (e.g., `0d2eabe`) or branch name (e.g., `main`). Find available previews at [pkg.pr.new/~/marcoroth/herb](https://pkg.pr.new/~/marcoroth/herb). + ##### Run ```bash diff --git a/javascript/packages/language-server/rollup.config.mjs b/javascript/packages/language-server/rollup.config.mjs index 5891c85eb..01568ac1b 100644 --- a/javascript/packages/language-server/rollup.config.mjs +++ b/javascript/packages/language-server/rollup.config.mjs @@ -12,6 +12,12 @@ const external = [ "module", ] +// Enable sourcemaps for local builds and release builds +// Disable for CI non-release builds (PR previews, etc.) +const isCI = process.env.CI === "true" +const isReleaseBuild = process.env.RELEASE_BUILD === "true" +const enableSourcemaps = !isCI || isReleaseBuild + function isExternal(id) { return ( external.includes(id) || @@ -19,6 +25,12 @@ function isExternal(id) { ) } +function allExternal(id) { + if (id.includes(".")) return false + + return true +} + export default [ // CLI entry point (CommonJS) { @@ -26,7 +38,7 @@ export default [ output: { file: "dist/herb-language-server.js", format: "cjs", - sourcemap: true, + sourcemap: enableSourcemaps, }, external: isExternal, plugins: [ @@ -47,9 +59,9 @@ export default [ output: { file: "dist/index.cjs", format: "cjs", - sourcemap: true, + sourcemap: enableSourcemaps, }, - external: isExternal, + external: allExternal, plugins: [ nodeResolve(), commonjs(), diff --git a/javascript/packages/linter/README.md b/javascript/packages/linter/README.md index db8c6af68..f17240074 100644 --- a/javascript/packages/linter/README.md +++ b/javascript/packages/linter/README.md @@ -36,6 +36,16 @@ For occasional use without installing: npx @herb-tools/linter template.html.erb ``` +### Preview Releases + +Want to try unreleased features? Use pkg.pr.new to run the linter from any commit or PR: + +```bash +npx https://pkg.pr.new/@herb-tools/linter@{commit} template.html.erb +``` + +Replace `{commit}` with a commit SHA (e.g., `0d2eabe`) or branch name (e.g., `main`). Find available previews at [pkg.pr.new/~/marcoroth/herb](https://pkg.pr.new/~/marcoroth/herb). + ### Project Installation :::code-group diff --git a/javascript/packages/stimulus-lint/rollup.config.mjs b/javascript/packages/stimulus-lint/rollup.config.mjs index 53c00a56d..6ad36d31c 100644 --- a/javascript/packages/stimulus-lint/rollup.config.mjs +++ b/javascript/packages/stimulus-lint/rollup.config.mjs @@ -12,6 +12,12 @@ const external = [ "module", ] +// Enable sourcemaps for local builds and release builds +// Disable for CI non-release builds (PR previews, etc.) +const isCI = process.env.CI === "true" +const isReleaseBuild = process.env.RELEASE_BUILD === "true" +const enableSourcemaps = !isCI || isReleaseBuild + function isExternal(id) { return ( external.includes(id) || @@ -26,7 +32,7 @@ export default [ output: { file: "dist/stimulus-lint.js", format: "cjs", - sourcemap: true, + sourcemap: enableSourcemaps, }, external: isExternal, plugins: [ @@ -47,9 +53,9 @@ export default [ output: { file: "dist/index.js", format: "esm", - sourcemap: true, + sourcemap: enableSourcemaps, }, - external: ["@herb-tools/core", "@herb-tools/linter", "@herb-tools/node-wasm", "stimulus-parser"], + external: ["@herb-tools/core", "@herb-tools/highlighter", "@herb-tools/linter", "@herb-tools/node-wasm", "stimulus-parser"], plugins: [ nodeResolve(), json(), @@ -65,11 +71,11 @@ export default [ // Library exports (CommonJS) { input: "src/index.ts", - external: ["@herb-tools/core", "@herb-tools/linter", "@herb-tools/node-wasm", "stimulus-parser"], + external: ["@herb-tools/core", "@herb-tools/highlighter", "@herb-tools/linter", "@herb-tools/node-wasm", "stimulus-parser"], output: { file: "dist/index.cjs", format: "cjs", - sourcemap: true, + sourcemap: enableSourcemaps, }, plugins: [ nodeResolve(), diff --git a/yarn.lock b/yarn.lock index b1e553cbc..fe37cfa2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2027,10 +2027,10 @@ "@types/expect" "^1.20.4" "@types/node" "*" -"@types/vscode@^1.105.0": - version "1.105.0" - resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.105.0.tgz#774c54cdb62409afeb0cb2a96f75c2e06ef3f97a" - integrity sha512-Lotk3CTFlGZN8ray4VxJE7axIyLZZETQJVWi/lYoUVQuqfRxlQhVOfoejsD2V3dVXPSbS15ov5ZyowMAzgUqcw== +"@types/vscode@^1.43.0": + version "1.106.0" + resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.106.0.tgz#abf54661998d1e76ef01bc8cf587450550631368" + integrity sha512-88oUcEl9Wmlyt64pbvjLzyyFuFuPotdjwy+P+5ggg3DyTJSMWJD3ShX2ppya5mqrAYTKEhcaJBerdc5JTeb32w== "@types/web-bluetooth@^0.0.21": version "0.0.21"