diff --git a/.changeset/violet-hornets-kick.md b/.changeset/violet-hornets-kick.md new file mode 100644 index 00000000..ef7d79d8 --- /dev/null +++ b/.changeset/violet-hornets-kick.md @@ -0,0 +1,5 @@ +--- +web-csv-toolbox: patch +--- + +Refactor CI/CD workflow diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml new file mode 100644 index 00000000..ede5e7f9 --- /dev/null +++ b/.github/actions/setup/action.yaml @@ -0,0 +1,51 @@ +name: Setup Action +description: Composite Setup Action + +inputs: + node-version: + description: Node.js version + required: false + default: '' + skip-rust-setup: + description: Skip Rust setup + required: false + default: 'false' + +runs: + using: composite + steps: + - name: Setup pnpm + uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 + - if: ${{ inputs.node-version == '' }} + name: Setup Node.js + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version-file: ./.node-version + cache: pnpm + - if: ${{ inputs.node-version != '' }} + name: Setup Node.js v${{ inputs.node-version }} + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: ${{ inputs.node-version }} + cache: pnpm + - name: Install Dependencies + run: pnpm install --frozen-lockfile + shell: bash + - name: Setup C++ + if: ${{ inputs.skip-rust-setup != 'true' }} + run: | + sudo apt-get update + sudo apt-get install libstdc++-12-dev + shell: bash + - name: Setup Rust + if: ${{ inputs.skip-rust-setup != 'true' }} + uses: moonrepo/setup-rust@d8048d4fdff0633123678b093726e6d7c8ad6de5 # v1.2.0 + with: + targets: wasm32-unknown-unknown + channel: nightly + components: clippy,rustfmt + target-dirs: web-csv-toolbox-wasm/target + - name: Install wasm-pack + if: ${{ inputs.skip-rust-setup != 'true' }} + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + shell: bash diff --git a/.github/workflows/.build.yaml b/.github/workflows/.build.yaml index bacfaaee..b15956b9 100644 --- a/.github/workflows/.build.yaml +++ b/.github/workflows/.build.yaml @@ -13,29 +13,14 @@ jobs: steps: - name: Checkout Repo uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - run: | - sudo apt-get update - sudo apt-get install libstdc++-12-dev - - name: Install latest - uses: moonrepo/setup-rust@d8048d4fdff0633123678b093726e6d7c8ad6de5 # v1.2.0 - with: - targets: wasm32-unknown-unknown - channel: nightly - target-dirs: web-csv-toolbox-wasm/target - - name: Install wasm-pack - run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - - name: Setup Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version-file: ./.node-version - cache: pnpm - - name: Install Dependencies - run: pnpm install --frozen-lockfile + - name: Setup + uses: ./.github/actions/setup - name: Build run: pnpm run build env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Type Check + run: pnpm check:type - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: dist diff --git a/.github/workflows/.dynamic-tests.yaml b/.github/workflows/.dynamic-tests.yaml new file mode 100644 index 00000000..ce11bef6 --- /dev/null +++ b/.github/workflows/.dynamic-tests.yaml @@ -0,0 +1,140 @@ +name: Dynamic Tests +on: + workflow_call: + secrets: + CODECOV_TOKEN: + required: true + description: The token to upload coverage reports to Codecov + CODSPEED_TOKEN: + required: true + description: The token to upload benchmarks to CodSpeed + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - name: Coverage + run: pnpm test:coverage + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + benchmarks: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - name: Run benchmarks + uses: CodSpeedHQ/action@f11c406b8c87cda176ff341ed4925bc98086f6d1 # v2.4.2 + with: + run: pnpm test:bench + token: ${{ secrets.CODSPEED_TOKEN }} + + test_nodejs: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x, 22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + node-version: ${{ matrix.node-version }} + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - run: pnpm test run + + + test_deno: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - uses: denoland/setup-deno@041b854f97b325bd60e53e9dc2de9cb9f9ac0cba # v1.1.4 + with: + deno-version: v1.x + - run: | + deno eval ' + import { parse } from "./dist/es/web-csv-toolbox.js"; + + const csv = `name,age + Alice,42 + Bob,69`; + + for await (const record of parse(csv)) { + console.log(record); + }' + + test_linux_browser: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + browsers: + - chrome + - firefox + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - run: npm test run -- --browser.name=${{ matrix.browsers }} --browser.headless + + test_macos_browser: + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + browsers: + - chrome + # TODO: Consider alternatives to frequent rate limit restrictions. + # - firefox + # NOTE: Headless Safari is currentry not supported + # https://github.com/vitest-dev/vitest/blob/main/packages/browser/src/node/providers/webdriver.ts#L39-L41 + # - safari + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + # - if: matrix.browsers == 'safari' + # run: sudo safaridriver --enable + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - run: pnpm test run -- --browser.name=${{ matrix.browsers }} --browser.headless + + + test_windows_browser: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + browsers: + - chrome + - firefox + - edge + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - run: pnpm test run -- --browser.name=${{ matrix.browsers }} --browser.headless diff --git a/.github/workflows/cd.yaml b/.github/workflows/.release.yaml similarity index 62% rename from .github/workflows/cd.yaml rename to .github/workflows/.release.yaml index c0fbea1b..34f0515d 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/.release.yaml @@ -1,29 +1,17 @@ -name: CD +name: Release on: - # Run this workflow when a workflow_run event is triggered - # from the "Node.js CI" workflows - # and the workflow_run's status is "completed" - # and the workflow_run's base branch is "main". - workflow_run: - workflows: [CI] - branches: [main] - types: [completed] - -concurrency: ${{ github.workflow }}-${{ github.ref }} + workflow_call: + secrets: + NPM_TOKEN: + required: true + description: The token to publish to npm jobs: - # Build the package and upload it as an artifact - build: - name: Build - uses: ./.github/workflows/.build.yaml # Release the package to npm release: name: Release runs-on: ubuntu-latest - needs: build - # Only run this job if the workflow_run's conclusion was "success" - if: ${{ github.event.workflow_run.conclusion == 'success' }} permissions: contents: write # Used to commit to "Version Packages" PR pull-requests: write # Used to create "Version Packages" PR @@ -32,14 +20,10 @@ jobs: steps: - name: Checkout Repo uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - - name: Setup Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + - name: Setup + uses: ./.github/actions/setup with: - node-version-file: ./.node-version - cache: pnpm - - name: Install Dependencies - run: pnpm install --frozen-lockfile + skip-rust-setup: 'true' - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - name: Create Release Pull Request or Publish to npm id: changesets @@ -53,7 +37,6 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} outputs: published: ${{ steps.changesets.outputs.published }} - # If the release job not published, run this job to publish a prerelease prerelease: name: Prerelease @@ -62,18 +45,13 @@ jobs: contents: read id-token: write needs: release - if: needs.release.outputs.published == 'false' steps: - name: Checkout uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - - name: Setup Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + - name: Setup + uses: ./.github/actions/setup with: - node-version-file: ./.node-version - cache: pnpm - - name: Install Dependencies - run: pnpm install --frozen-lockfile + skip-rust-setup: 'true' - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - name: Creating .npmrc if: ${{ github.actor != 'dependabot[bot]' }} @@ -95,7 +73,6 @@ jobs: runs-on: ubuntu-latest # if the release job was successful, run this job needs: - - build - release if: needs.release.outputs.published == 'true' concurrency: @@ -110,17 +87,10 @@ jobs: id-token: write steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - - name: Setup Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + - name: Setup + uses: ./.github/actions/setup with: - node-version-file: ./.node-version - cache: pnpm - - name: Install Dependencies - run: pnpm install --frozen-lockfile - - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - - name: Build - run: pnpm build:js + skip-rust-setup: 'true' - name: Build documentation run: pnpm run doc - name: Configure GitHub Pages diff --git a/.github/workflows/.static-tests.yaml b/.github/workflows/.static-tests.yaml new file mode 100644 index 00000000..f0fce4b0 --- /dev/null +++ b/.github/workflows/.static-tests.yaml @@ -0,0 +1,38 @@ +name: Static Tests + +on: + workflow_call: +jobs: + check_format: + name: Check format + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout Repo + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + - name: Check + run: pnpm check:format + + check_clippy_and_rustfmt: + name: Check with clippy and rustfmt + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout Repo + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Setup + uses: ./.github/actions/setup + with: + skip-rust-setup: 'true' + - name: Run Clippy + run: cargo clippy --manifest-path=./web-csv-toolbox-wasm/Cargo.toml --all-targets --all-features + env: + RUSTFLAGS: -D warnings + - name: Run Fmt + run: cargo fmt --manifest-path=./web-csv-toolbox-wasm/Cargo.toml --all -- --check diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 00000000..eb1f3a4d --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,43 @@ +name: Main Workflow +on: + push: + branches: + - main + pull_request: + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + + static_tests: + name: Static Tests + uses: ./.github/workflows/.static-tests.yaml + + build: + name: Build + uses: ./.github/workflows/.build.yaml + needs: + - static_tests + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + dynamic_tests: + name: Dynamic Tests + uses: ./.github/workflows/.dynamic-tests.yaml + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODSPEED_TOKEN: ${{ secrets.CODSPEED_TOKEN }} + needs: + - build + - static_tests + + release: + name: Release + uses: ./.github/workflows/.release.yaml + needs: + - static_tests + - build + - dynamic_tests + if: ${{ github.repository == 'kamiazya/web-csv-toolbox' && github.ref == 'refs/heads/main' && success() }} + secrets: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/pr-snapshot-release.yaml b/.github/workflows/pr-snapshot-release.yaml index b3dd4a63..f56b80c3 100644 --- a/.github/workflows/pr-snapshot-release.yaml +++ b/.github/workflows/pr-snapshot-release.yaml @@ -88,14 +88,8 @@ jobs: git checkout origin/main -- .changeset fi - - name: Setup Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version-file: ./.node-version - - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - - name: Install dependencies - run: pnpm install --frozen-lockfile - - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - name: Setup + uses: ./.github/actions/setup - name: Create an .npmrc run: | cat << EOF > "$HOME/.npmrc"