diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2c645d45..ee036f56 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -14,12 +14,55 @@ defaults: shell: bash jobs: + list-astro-versions: + runs-on: ubuntu-24.04 + timeout-minutes: 10 + permissions: + contents: read # for checkout + + outputs: + astro-versions: ${{ steps.list.outputs.versions }} + + steps: + - name: Checkout + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - name: Install mise + uses: jdx/mise-action@f8dfbcc150159126838e44b882bf34bd98fd90f3 # v2.1.0 + with: + experimental: true + install: false + + - name: Install mise tools + # cspell:ignore reshim + # reshim is required to avoid "No such file or directory" error + # ref: https://github.com/jdx/mise/issues/2260 + run: mise install || (mise reshim && mise install) + + - name: Install package.json dependencies + run: mise run buni + + - name: List astro versions for E2E tests + id: list + run: | + versions=$(bun run .github/workflows/scripts/list-astro-versions.ts) + echo "versions=$versions" >> "$GITHUB_OUTPUT" + test-e2e-general: + needs: + - list-astro-versions + runs-on: ubuntu-24.04 timeout-minutes: 10 permissions: contents: read # for checkout + name: test-e2e-general-astro-${{ matrix.version }} + strategy: + fail-fast: false + matrix: + version: ${{ fromJson(needs.list-astro-versions.outputs.astro-versions) }} + steps: - name: Checkout uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 @@ -43,7 +86,7 @@ jobs: run: mise run build - name: Install E2E Test Fixtures Dependencies - run: bun install --frozen-lockfile + run: bun install astro@${{ matrix.version }} working-directory: tests/e2e/fixtures - name: Build E2E Test Fixtures with astro-better-image-service @@ -89,7 +132,7 @@ jobs: if: failure() && steps.playwright-test.outcome == 'failure' uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: - name: playwright-report-${{ github.sha }} + name: playwright-report-astro-${{ matrix.version }}-${{ github.sha }} path: playwright-report/ test-e2e-conversion: @@ -124,7 +167,12 @@ jobs: id: dependency-versions run: | playwright_version=$(bun pm ls | sed -nE 's/.*@playwright\/test@(.+)/\1/p') - astro_version=$(bun pm ls | sed -nE 's/.*astro@(.+)/\1/p') + astro_version=$(bun pm ls | sed -nE 's/.*astro@(.+)/\1/p' | uniq) + # throw error if several versions are found + if [[ $(echo "$astro_version" | wc -l) -gt 1 ]]; then + echo "Multiple versions of Astro found: $astro_version" + exit 1 + fi echo "playwright=$playwright_version" >> "$GITHUB_OUTPUT" echo "astro=$astro_version" >> "$GITHUB_OUTPUT" @@ -203,7 +251,7 @@ jobs: name: playwright-report-conversion-${{ github.sha }} path: playwright-report/ - actions-timeline: + test-e2e-status: needs: - test-e2e-general - test-e2e-conversion @@ -211,6 +259,24 @@ jobs: # skip if the workflow is called from another workflow if: ${{ !cancelled() && contains(github.workflow_ref, '/e2e.yml') }} + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + steps: + - name: Check the status of the jobs + run: | + if [[ $(echo '${{ toJson(needs.*.result) }}' | jq 'all(. == "success")') == "false" ]]; then + echo 'Some jobs are failed, cancelled, or skipped.' + exit 1 + fi + echo 'All jobs are successful.' + + actions-timeline: + needs: + - test-e2e-status + + if: needs.test-e2e-status.result == 'success' || needs.test-e2e-status.result == 'failure' + runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f4121fa0..12d23f6a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -148,7 +148,7 @@ jobs: if: steps.commitlint-push-initial.outcome == 'skipped' && steps.commitlint-push.outcome == 'skipped' && steps.commitlint-pr.outcome == 'skipped' run: bun run commitlint --verbose --from ${{ github.sha }}~1 --to ${{ github.sha }} - actions-timeline: + lint-status: needs: - lint - lint-commitlint @@ -156,6 +156,24 @@ jobs: # skip if the workflow is called from another workflow if: ${{ !cancelled() && contains(github.workflow_ref, '/lint.yml') }} + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + steps: + - name: Check the status of the jobs + run: | + if [[ $(echo '${{ toJson(needs.*.result) }}' | jq 'all(. == "success")') == "false" ]]; then + echo 'Some jobs are failed, cancelled, or skipped.' + exit 1 + fi + echo 'All jobs are successful.' + + actions-timeline: + needs: + - lint-status + + if: needs.lint-status.result == 'success' || needs.lint-status.result == 'failure' + runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: diff --git a/.github/workflows/scripts/list-astro-versions.ts b/.github/workflows/scripts/list-astro-versions.ts new file mode 100644 index 00000000..fe426e6e --- /dev/null +++ b/.github/workflows/scripts/list-astro-versions.ts @@ -0,0 +1,38 @@ +import { $ } from "bun"; +import { compare, parse, satisfies } from "semver"; +import packageJson from "../../../package.json" with { type: "json" }; + +$.throws(true); + +const peerRange = packageJson.peerDependencies.astro as string; + +const versions = (await $`npm view astro versions --json`.json()) as string[]; + +const versionsInRange = versions + .filter((version) => satisfies(version, peerRange)) + .sort(compare); + +const groupedVersions = Object.groupBy(versionsInRange, (version) => { + const semver = parse(version); + if (!semver) { + throw new Error(`Invalid version: ${version}`); + } + return `${semver.major}.${semver.minor}`; +}); + +const versionsToTest = [ + ...new Set([ + // oldest 3 versions + ...versionsInRange.slice(0, 3), + // oldest version of each major version + ...Object.entries(groupedVersions) + .filter(([key]) => key.endsWith(".0")) + .map(([, versions]) => versions?.at(0)), + // latest version of each minor version + ...Object.values(groupedVersions).map((versions) => versions?.at(-1)), + // latest 5 versions + ...versionsInRange.slice(-5), + ]), +]; + +console.write(JSON.stringify(versionsToTest)); diff --git a/bun.lockb b/bun.lockb index 99c192f0..774c6ddf 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/knip.config.ts b/knip.config.ts index 7e7aa3d3..0992625b 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -7,17 +7,19 @@ const config: KnipConfig = { workspaces: { ".": { ignoreDependencies: [ - // mise.toml is not recognized by Knip + // mise.toml is not recognized "@biomejs/biome", "cspell", "ignore-sync", "markdownlint-cli2", "renovate", - // bun run cannot be detected by Knip + // bun run cannot be detected "@commitlint/cli", "semantic-release", ], entry: ["src/index.ts", "**/scripts/**"], + // peerDependencies are not recognized as plugins + astro: true, }, "tests/e2e/fixtures": {}, }, diff --git a/package.json b/package.json index cfcf9770..0f8de6ec 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,11 @@ "prepare": "husky && bun link" }, "dependencies": { - "astro": "4.15.11", - "sharp": "0.33.5", - "svgo": "3.3.2" + "sharp": "^0.33.5", + "svgo": "^3.3.2" + }, + "peerDependencies": { + "astro": "^4.7.0" }, "devDependencies": { "@biomejs/biome": "1.9.3", @@ -45,6 +47,7 @@ "ajv": "8.17.1", "ajv-draft-04": "1.0.0", "ajv-formats": "3.0.1", + "astro": "4.15.11", "commitizen": "4.3.1", "cspell": "8.14.4", "husky": "9.1.6", @@ -57,6 +60,7 @@ "prettier": "3.3.3", "renovate": "38.110.2", "semantic-release": "24.1.2", + "semver": "7.6.3", "ts-graphviz": "2.1.4", "typescript": "5.6.2" }, diff --git a/renovate.json5 b/renovate.json5 index 5a48d99c..770e5642 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -82,7 +82,24 @@ }, ], packageRules: [ + // disable pinning for dependencies and peerDependencies + { + matchFileNames: ["package.json"], + matchDepTypes: ["dependencies"], + // bump for dependencies and release a patch update + rangeStrategy: "bump", + }, + { + matchFileNames: ["package.json"], + matchDepTypes: ["peerDependencies"], + // widen range for peerDependencies as far as possible + rangeStrategy: "widen", + }, // set semantic commit types + { + matchFileNames: ["tests/"], + semanticCommitType: "test", + }, { matchCategories: ["ci"], semanticCommitType: "ci", diff --git a/tests/e2e/fixtures/bun.lockb b/tests/e2e/fixtures/bun.lockb index 9d198c49..bb3a86af 100755 Binary files a/tests/e2e/fixtures/bun.lockb and b/tests/e2e/fixtures/bun.lockb differ diff --git a/tests/e2e/fixtures/package.json b/tests/e2e/fixtures/package.json index 17c330c7..903b7d4c 100644 --- a/tests/e2e/fixtures/package.json +++ b/tests/e2e/fixtures/package.json @@ -3,6 +3,7 @@ "private": true, "type": "module", "dependencies": { + "astro": "4.15.11", "astro-better-image-service": "link:astro-better-image-service" }, "scripts": {