Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Rework image generation to improve performance #8821

Merged
merged 14 commits into from
Oct 25, 2023

Conversation

Princesseuh
Copy link
Member

@Princesseuh Princesseuh commented Oct 13, 2023

Changes

Change how image generation is done to improve performance:

  • Images are now grouped under the base image (or URL) they originate from, as such, we can reuse the same buffer to generate all the variants, whereas before we would reload / refetch the image for every variant
  • Adds a concurrent promise queue for image generations. Image generation plays well with being done concurrently, so it's a massive performance increase in a lot of cases, especially for uncached runs.
  • Previously we'd do a lot of work to setup image generation on every image. This is now only done once and shared across all calls.

On my website, that has 222 local images, here's the result:

Before

  • Fresh build: 26s~
  • Cached build: 2s~

After

  • Fresh build: 8s~
  • Cached: 2s~

Not exactly scientific, but there's definitely an improvement in there.

Testing

Tests should still pass!

Docs

N/A.

@changeset-bot
Copy link

changeset-bot bot commented Oct 13, 2023

🦋 Changeset detected

Latest commit: ecdc634

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Oct 13, 2023
@github-actions github-actions bot added the semver: minor Change triggers a `minor` release label Oct 13, 2023
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is blocked because it contains a minor changeset. A reviewer will merge this at the next release if approved.

@Princesseuh
Copy link
Member Author

!preview concurrent-assets

@github-actions
Copy link
Contributor

 > root@0.0.0 release /home/runner/work/astro/astro > pnpm run build && changeset publish "--tag" "next--concurrent-assets" > root@0.0.0 build /home/runner/work/astro/astro > turbo run build --filter=astro --filter=create-astro --filter="@astrojs/*" --filter="@benchmark/*" �[2m• Packages in scope: @astrojs/alpinejs, @astrojs/cloudflare, @astrojs/internal-helpers, @astrojs/lit, @astrojs/markdoc, @astrojs/markdown-remark, @astrojs/mdx, @astrojs/netlify, @astrojs/node, @astrojs/partytown, @astrojs/preact, @astrojs/prefetch, @astrojs/prism, @astrojs/react, @astrojs/rss, @astrojs/sitemap, @astrojs/solid-js, @astrojs/svelte, @astrojs/tailwind, @astrojs/telemetry, @astrojs/underscore-redirects, @astrojs/vercel, @astrojs/vue, @benchmark/timer, astro, create-astro�[0m �[2m• Running�[0m �[2m�[1mbuild�[0m�[0m �[2min 26 packages�[0m �[2m• Remote caching enabled�[0m ::group::@astrojs/telemetry:build cache hit, suppressing logs �[2m8f791e5bb7108651�[0m ::endgroup:: ::group::create-astro:build cache hit, suppressing logs �[2mb92067e8d3d6f572�[0m ::endgroup:: ::group::@astrojs/prism:build cache hit, suppressing logs �[2m1fbe4acc344b9100�[0m ::endgroup:: ::group::@astrojs/internal-helpers:build cache hit, suppressing logs �[2mc6ad1a8f27dca66f�[0m ::endgroup:: ::group::@astrojs/markdown-remark:build cache miss, executing �[2m5ea7eda930ba6d10�[0m > @astrojs/markdown-remark@3.3.0 build /home/runner/work/astro/astro/packages/markdown/remark > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json ::endgroup:: ::group::astro:build cache miss, executing �[2m0ccfb63b28683afe�[0m > astro@0.0.0-concurrent-assets-20231013074530 build /home/runner/work/astro/astro/packages/astro > pnpm run prebuild && astro-scripts build "src/**/*.{ts,js}" && tsc && pnpm run postbuild > astro@0.0.0-concurrent-assets-20231013074530 prebuild /home/runner/work/astro/astro/packages/astro > astro-scripts prebuild --to-string "src/runtime/server/astro-island.ts" "src/runtime/client/{idle,load,media,only,visible}.ts" > astro@0.0.0-concurrent-assets-20231013074530 postbuild /home/runner/work/astro/astro/packages/astro > astro-scripts copy "src/**/*.astro" && astro-scripts copy "src/**/*.wasm" ::endgroup:: ::group::@astrojs/tailwind:build cache miss, executing �[2m43575c21f321e41a�[0m > @astrojs/tailwind@5.0.2 build /home/runner/work/astro/astro/packages/integrations/tailwind > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@benchmark/timer:build cache miss, executing �[2m6ad2cbba1a3e87ac�[0m > @benchmark/timer@0.0.0 build /home/runner/work/astro/astro/benchmark/packages/timer > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/alpinejs:build cache miss, executing �[2ma4883591bfa646cc�[0m > @astrojs/alpinejs@0.3.1 build /home/runner/work/astro/astro/packages/integrations/alpinejs > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/rss:build cache miss, executing �[2m916d09de3cb1b9c1�[0m > @astrojs/rss@3.0.0 build /home/runner/work/astro/astro/packages/astro-rss > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/underscore-redirects:build cache miss, executing �[2m4a9956bcf71851f3�[0m > @astrojs/underscore-redirects@0.3.1 build /home/runner/work/astro/astro/packages/underscore-redirects > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json ::endgroup:: ::group::@astrojs/solid-js:build cache miss, executing �[2m346207eff4a804a0�[0m > @astrojs/solid-js@3.0.2 build /home/runner/work/astro/astro/packages/integrations/solid > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/react:build cache miss, executing �[2m568ce00f995e21ef�[0m > @astrojs/react@3.0.3 build /home/runner/work/astro/astro/packages/integrations/react > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/vue:build cache miss, executing �[2m07c508f88bdd89d7�[0m > @astrojs/vue@3.0.1 build /home/runner/work/astro/astro/packages/integrations/vue > astro-scripts build "src/index.ts" && astro-scripts build "src/editor.cts" --force-cjs --no-clean-dist && tsc ::endgroup:: ::group::@astrojs/node:build cache miss, executing �[2m69d2eb068a7ce2f7�[0m > @astrojs/node@6.0.3 build /home/runner/work/astro/astro/packages/integrations/node > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/vercel:build cache miss, executing �[2m46342f7ab860eca6�[0m > @astrojs/vercel@5.0.2 build /home/runner/work/astro/astro/packages/integrations/vercel > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/prefetch:build cache miss, executing �[2mf2e3415846b5de12�[0m > @astrojs/prefetch@0.4.1 build /home/runner/work/astro/astro/packages/integrations/prefetch > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/partytown:build cache miss, executing �[2m5eaa8b668218f4fd�[0m > @astrojs/partytown@2.0.1 build /home/runner/work/astro/astro/packages/integrations/partytown > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/preact:build cache miss, executing �[2m2a8d6fd201949213�[0m > @astrojs/preact@3.0.1 build /home/runner/work/astro/astro/packages/integrations/preact > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/lit:build cache miss, executing �[2mfbf732baa5214d74�[0m > @astrojs/lit@3.0.1 build /home/runner/work/astro/astro/packages/integrations/lit > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/mdx:build cache miss, executing �[2m40b6660e7568f747�[0m > @astrojs/mdx@1.1.2 build /home/runner/work/astro/astro/packages/integrations/mdx > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/svelte:build cache miss, executing �[2m1e8f2fd290cbd246�[0m > @astrojs/svelte@4.0.3 build /home/runner/work/astro/astro/packages/integrations/svelte > astro-scripts build "src/index.ts" && astro-scripts build "src/editor.cts" --force-cjs --no-clean-dist && tsc ::endgroup:: ::group::@astrojs/markdoc:build cache miss, executing �[2mca30c416d6c8e995�[0m > @astrojs/markdoc@0.6.0 build /home/runner/work/astro/astro/packages/integrations/markdoc > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/sitemap:build cache miss, executing �[2mf2639d6f65bf16d1�[0m > @astrojs/sitemap@3.0.1 build /home/runner/work/astro/astro/packages/integrations/sitemap > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/cloudflare:build cache miss, executing �[2m64a9491d7ee6635e�[0m > @astrojs/cloudflare@7.5.3 build /home/runner/work/astro/astro/packages/integrations/cloudflare > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: Tasks: 25 successful, 25 total Cached: 4 cached, 25 total Time: 1m7.341s 🦋 �[33mwarn�[39m �[31m===============================IMPORTANT!===============================�[39m 🦋 �[33mwarn�[39m Packages will be released under the next--concurrent-assets tag 🦋 �[33mwarn�[39m �[31m----------------------------------------------------------------------�[39m 🦋 �[36minfo�[39m npm info astro 🦋 �[36minfo�[39m npm info @astrojs/prism 🦋 �[36minfo�[39m npm info @astrojs/rss 🦋 �[36minfo�[39m npm info create-astro 🦋 �[36minfo�[39m npm info @astrojs/alpinejs 🦋 �[36minfo�[39m npm info @astrojs/cloudflare 🦋 �[36minfo�[39m npm info @astrojs/lit 🦋 �[36minfo�[39m npm info @astrojs/markdoc 🦋 �[36minfo�[39m npm info @astrojs/mdx 🦋 �[36minfo�[39m npm info @astrojs/node 🦋 �[36minfo�[39m npm info @astrojs/partytown 🦋 �[36minfo�[39m npm info @astrojs/preact 🦋 �[36minfo�[39m npm info @astrojs/prefetch 🦋 �[36minfo�[39m npm info @astrojs/react 🦋 �[36minfo�[39m npm info @astrojs/sitemap 🦋 �[36minfo�[39m npm info @astrojs/solid-js 🦋 �[36minfo�[39m npm info @astrojs/svelte 🦋 �[36minfo�[39m npm info @astrojs/tailwind 🦋 �[36minfo�[39m npm info @astrojs/vercel 🦋 �[36minfo�[39m npm info @astrojs/vue 🦋 �[36minfo�[39m npm info @astrojs/internal-helpers 🦋 �[36minfo�[39m npm info @astrojs/markdown-remark 🦋 �[36minfo�[39m npm info @astrojs/telemetry 🦋 �[36minfo�[39m npm info @astrojs/underscore-redirects 🦋 �[36minfo�[39m astro is being published because our local version (0.0.0-concurrent-assets-20231013074530) has not been published on npm 🦋 �[33mwarn�[39m @astrojs/prism is not being published because version 3.0.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/rss is not being published because version 3.0.0 is already published on npm 🦋 �[33mwarn�[39m create-astro is not being published because version 4.2.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/alpinejs is not being published because version 0.3.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/cloudflare is not being published because version 7.5.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/lit is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/markdoc is not being published because version 0.6.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/mdx is not being published because version 1.1.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/node is not being published because version 6.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/partytown is not being published because version 2.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/preact is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/prefetch is not being published because version 0.4.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/react is not being published because version 3.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/sitemap is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/solid-js is not being published because version 3.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/svelte is not being published because version 4.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/tailwind is not being published because version 5.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/vercel is not being published because version 5.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/vue is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/internal-helpers is not being published because version 0.2.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/markdown-remark is not being published because version 3.3.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/telemetry is not being published because version 3.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/underscore-redirects is not being published because version 0.3.1 is already published on npm 🦋 �[36minfo�[39m Publishing �[36m"astro"�[39m at �[32m"0.0.0-concurrent-assets-20231013074530"�[39m 🦋 �[32msuccess�[39m packages published successfully: 🦋 astro@0.0.0-concurrent-assets-20231013074530 🦋 Creating git tag... 🦋 New tag: astro@0.0.0-concurrent-assets-20231013074530

@itsmatteomanf
Copy link
Contributor

We need to be able to detect when a file is empty as with multiple writers/readers you can get into a situation in which the generation crashes with a file generated and not written.

This in turn causes the next build to fail with the ENOENT error. If the file is empty it should be ignored, imho.

packages/astro/src/core/build/generate.ts Outdated Show resolved Hide resolved
@itsmatteomanf
Copy link
Contributor

Do we want to consider a way to set the cpu count manually?

In some instances one might want to reduce the parallelisation if the backend doesn't support it for remote images, or something...

Comment on lines +21 to +24
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
ignoreRestSiblings: true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to the PR, but it was driving me nuts

@Princesseuh
Copy link
Member Author

!preview concurrent-assets

@github-actions
Copy link
Contributor

 > root@0.0.0 release /home/runner/work/astro/astro > pnpm run build && changeset publish "--tag" "next--concurrent-assets" > root@0.0.0 build /home/runner/work/astro/astro > turbo run build --filter=astro --filter=create-astro --filter="@astrojs/*" --filter="@benchmark/*" �[2m• Packages in scope: @astrojs/alpinejs, @astrojs/cloudflare, @astrojs/internal-helpers, @astrojs/lit, @astrojs/markdoc, @astrojs/markdown-remark, @astrojs/mdx, @astrojs/netlify, @astrojs/node, @astrojs/partytown, @astrojs/preact, @astrojs/prefetch, @astrojs/prism, @astrojs/react, @astrojs/rss, @astrojs/sitemap, @astrojs/solid-js, @astrojs/svelte, @astrojs/tailwind, @astrojs/telemetry, @astrojs/underscore-redirects, @astrojs/vercel, @astrojs/vue, @benchmark/timer, astro, create-astro�[0m �[2m• Running�[0m �[2m�[1mbuild�[0m�[0m �[2min 26 packages�[0m �[2m• Remote caching enabled�[0m ::group::@astrojs/prism:build cache miss, executing �[2m1fbe4acc344b9100�[0m > @astrojs/prism@3.0.0 build /home/runner/work/astro/astro/packages/astro-prism > astro-scripts build "src/**/*.ts" && tsc -p ./tsconfig.json ::endgroup:: ::group::@astrojs/internal-helpers:build cache miss, executing �[2mc6ad1a8f27dca66f�[0m > @astrojs/internal-helpers@0.2.1 build /home/runner/work/astro/astro/packages/internal-helpers > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json ::endgroup:: ::group::@astrojs/telemetry:build cache miss, executing �[2m8f791e5bb7108651�[0m > @astrojs/telemetry@3.0.3 build /home/runner/work/astro/astro/packages/telemetry > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/markdown-remark:build cache hit, suppressing logs �[2m5ea7eda930ba6d10�[0m ::endgroup:: ::group::create-astro:build cache miss, executing �[2mb92067e8d3d6f572�[0m > create-astro@4.2.1 build /home/runner/work/astro/astro/packages/create-astro > astro-scripts build "src/index.ts" --bundle && tsc ::endgroup:: ::group::astro:build cache miss, executing �[2m4af926bdfb693e44�[0m > astro@0.0.0-concurrent-assets-20231015171336 build /home/runner/work/astro/astro/packages/astro > pnpm run prebuild && astro-scripts build "src/**/*.{ts,js}" && tsc && pnpm run postbuild > astro@0.0.0-concurrent-assets-20231015171336 prebuild /home/runner/work/astro/astro/packages/astro > astro-scripts prebuild --to-string "src/runtime/server/astro-island.ts" "src/runtime/client/{idle,load,media,only,visible}.ts" > astro@0.0.0-concurrent-assets-20231015171336 postbuild /home/runner/work/astro/astro/packages/astro > astro-scripts copy "src/**/*.astro" && astro-scripts copy "src/**/*.wasm" ::endgroup:: ::group::@astrojs/underscore-redirects:build cache miss, executing �[2mfcdb94c84a5697cd�[0m > @astrojs/underscore-redirects@0.3.1 build /home/runner/work/astro/astro/packages/underscore-redirects > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json ::endgroup:: ::group::@benchmark/timer:build cache miss, executing �[2m913919195cecb3f8�[0m > @benchmark/timer@0.0.0 build /home/runner/work/astro/astro/benchmark/packages/timer > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/partytown:build cache miss, executing �[2mdff168d1f41cb38c�[0m > @astrojs/partytown@2.0.1 build /home/runner/work/astro/astro/packages/integrations/partytown > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/rss:build cache miss, executing �[2mb276bef7912e8d2f�[0m > @astrojs/rss@3.0.0 build /home/runner/work/astro/astro/packages/astro-rss > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/lit:build cache miss, executing �[2me6b41e7b3f7ed8b7�[0m > @astrojs/lit@3.0.1 build /home/runner/work/astro/astro/packages/integrations/lit > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/prefetch:build cache miss, executing �[2m9704d665cc19bc15�[0m > @astrojs/prefetch@0.4.1 build /home/runner/work/astro/astro/packages/integrations/prefetch > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/node:build cache miss, executing �[2ma7908ae6d54bca29�[0m > @astrojs/node@6.0.3 build /home/runner/work/astro/astro/packages/integrations/node > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/svelte:build cache miss, executing �[2medd804ebe388c034�[0m > @astrojs/svelte@4.0.3 build /home/runner/work/astro/astro/packages/integrations/svelte > astro-scripts build "src/index.ts" && astro-scripts build "src/editor.cts" --force-cjs --no-clean-dist && tsc ::endgroup:: ::group::@astrojs/vue:build cache miss, executing �[2m4eef3112c6b080ce�[0m > @astrojs/vue@3.0.1 build /home/runner/work/astro/astro/packages/integrations/vue > astro-scripts build "src/index.ts" && astro-scripts build "src/editor.cts" --force-cjs --no-clean-dist && tsc ::endgroup:: ::group::@astrojs/markdoc:build cache miss, executing �[2m6c3b68dea74b9124�[0m > @astrojs/markdoc@0.6.0 build /home/runner/work/astro/astro/packages/integrations/markdoc > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/alpinejs:build cache miss, executing �[2m63390f6195d30058�[0m > @astrojs/alpinejs@0.3.1 build /home/runner/work/astro/astro/packages/integrations/alpinejs > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/tailwind:build cache miss, executing �[2m87f0a1bd99fdbbdc�[0m > @astrojs/tailwind@5.0.2 build /home/runner/work/astro/astro/packages/integrations/tailwind > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/react:build cache miss, executing �[2m530c78e94c2f2a69�[0m > @astrojs/react@3.0.3 build /home/runner/work/astro/astro/packages/integrations/react > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/preact:build cache miss, executing �[2m9b3b2f1e83c6245b�[0m > @astrojs/preact@3.0.1 build /home/runner/work/astro/astro/packages/integrations/preact > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/vercel:build cache miss, executing �[2m185c0b1e214365fc�[0m > @astrojs/vercel@5.0.2 build /home/runner/work/astro/astro/packages/integrations/vercel > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/mdx:build cache miss, executing �[2m14fa75a8abfde1a7�[0m > @astrojs/mdx@1.1.2 build /home/runner/work/astro/astro/packages/integrations/mdx > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/solid-js:build cache miss, executing �[2m5b650b9569924362�[0m > @astrojs/solid-js@3.0.2 build /home/runner/work/astro/astro/packages/integrations/solid > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/cloudflare:build cache miss, executing �[2mcf052d386215d874�[0m > @astrojs/cloudflare@7.5.3 build /home/runner/work/astro/astro/packages/integrations/cloudflare > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/sitemap:build cache miss, executing �[2mbf70bd3ef1b58128�[0m > @astrojs/sitemap@3.0.1 build /home/runner/work/astro/astro/packages/integrations/sitemap > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: Tasks: 25 successful, 25 total Cached: 1 cached, 25 total Time: 1m13.561s 🦋 �[33mwarn�[39m �[31m===============================IMPORTANT!===============================�[39m 🦋 �[33mwarn�[39m Packages will be released under the next--concurrent-assets tag 🦋 �[33mwarn�[39m �[31m----------------------------------------------------------------------�[39m 🦋 �[36minfo�[39m npm info astro 🦋 �[36minfo�[39m npm info @astrojs/prism 🦋 �[36minfo�[39m npm info @astrojs/rss 🦋 �[36minfo�[39m npm info create-astro 🦋 �[36minfo�[39m npm info @astrojs/alpinejs 🦋 �[36minfo�[39m npm info @astrojs/cloudflare 🦋 �[36minfo�[39m npm info @astrojs/lit 🦋 �[36minfo�[39m npm info @astrojs/markdoc 🦋 �[36minfo�[39m npm info @astrojs/mdx 🦋 �[36minfo�[39m npm info @astrojs/node 🦋 �[36minfo�[39m npm info @astrojs/partytown 🦋 �[36minfo�[39m npm info @astrojs/preact 🦋 �[36minfo�[39m npm info @astrojs/prefetch 🦋 �[36minfo�[39m npm info @astrojs/react 🦋 �[36minfo�[39m npm info @astrojs/sitemap 🦋 �[36minfo�[39m npm info @astrojs/solid-js 🦋 �[36minfo�[39m npm info @astrojs/svelte 🦋 �[36minfo�[39m npm info @astrojs/tailwind 🦋 �[36minfo�[39m npm info @astrojs/vercel 🦋 �[36minfo�[39m npm info @astrojs/vue 🦋 �[36minfo�[39m npm info @astrojs/internal-helpers 🦋 �[36minfo�[39m npm info @astrojs/markdown-remark 🦋 �[36minfo�[39m npm info @astrojs/telemetry 🦋 �[36minfo�[39m npm info @astrojs/underscore-redirects 🦋 �[36minfo�[39m astro is being published because our local version (0.0.0-concurrent-assets-20231015171336) has not been published on npm 🦋 �[33mwarn�[39m @astrojs/prism is not being published because version 3.0.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/rss is not being published because version 3.0.0 is already published on npm 🦋 �[33mwarn�[39m create-astro is not being published because version 4.2.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/alpinejs is not being published because version 0.3.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/cloudflare is not being published because version 7.5.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/lit is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/markdoc is not being published because version 0.6.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/mdx is not being published because version 1.1.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/node is not being published because version 6.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/partytown is not being published because version 2.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/preact is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/prefetch is not being published because version 0.4.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/react is not being published because version 3.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/sitemap is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/solid-js is not being published because version 3.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/svelte is not being published because version 4.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/tailwind is not being published because version 5.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/vercel is not being published because version 5.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/vue is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/internal-helpers is not being published because version 0.2.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/markdown-remark is not being published because version 3.3.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/telemetry is not being published because version 3.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/underscore-redirects is not being published because version 0.3.1 is already published on npm 🦋 �[36minfo�[39m Publishing �[36m"astro"�[39m at �[32m"0.0.0-concurrent-assets-20231015171336"�[39m 🦋 �[32msuccess�[39m packages published successfully: 🦋 astro@0.0.0-concurrent-assets-20231015171336 🦋 Creating git tag... 🦋 New tag: astro@0.0.0-concurrent-assets-20231015171336

@Princesseuh
Copy link
Member Author

@bluwy @ematipico I kinda rewrote it all from scratch 🙈. I updated the PR description to reflect what was done and would love to see a re-review from you both! (I made os lower case)

@Princesseuh Princesseuh changed the title feat: implement concurrency for asset generation feat: Rework image generation to improve performance Oct 15, 2023
env: AssetEnv,
queue: PQueue
) {
const originalImageData = await loadImage(originalFilePath, env);
Copy link
Member Author

@Princesseuh Princesseuh Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory, the fact that we load the image at the beginning even when all the transforms might be cached already is slower, especially for fully cached builds where there's a lot of different images with a small amount of variants. However, in practice I found that this didn't change much, probably that the rest of the improvements counteract this, or maybe hard drives are just fast enough now.

If we want to get it of this, what we could probably do is store a list of cached hashes and check first if all the transforms requested are already cached before loading the image, shouldn't be too hard.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should apply your suggestions, probably in a follow-up PR. An I/O operation is usually more expensive than a memory operation, and even though Node.js is really great in I/O operations, I think we should try to avoid them if we can.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I definitely agree, but I think it's not as bad as it might seems because the file is already written in the same process, so it's presumably already in some sort of hot cache.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we also make originalImageData a function to lazily load it, and those who call in parallel would share the same cache? Vite has this utility (which could be generalized) to simplify a bit.

But also I think we can do it in a follow-up too if there's not a big perf impact currently.

Comment on lines +215 to +217
for (const [originalPath, transforms] of staticImageList) {
await generateImagesForPath(originalPath, transforms, assetsCreationEnvironment, queue);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A question someone might have: Would make this part concurrent help?

No (at least as far as I can tell), it doesn't really matter if the queue is full of variants from one image vs variants of multiple images.

@Princesseuh
Copy link
Member Author

!preview concurrent-assets

@github-actions
Copy link
Contributor

 > root@0.0.0 release /home/runner/work/astro/astro > pnpm run build && changeset publish "--tag" "next--concurrent-assets" > root@0.0.0 build /home/runner/work/astro/astro > turbo run build --filter=astro --filter=create-astro --filter="@astrojs/*" --filter="@benchmark/*" �[2m• Packages in scope: @astrojs/alpinejs, @astrojs/cloudflare, @astrojs/internal-helpers, @astrojs/lit, @astrojs/markdoc, @astrojs/markdown-remark, @astrojs/mdx, @astrojs/netlify, @astrojs/node, @astrojs/partytown, @astrojs/preact, @astrojs/prefetch, @astrojs/prism, @astrojs/react, @astrojs/rss, @astrojs/sitemap, @astrojs/solid-js, @astrojs/svelte, @astrojs/tailwind, @astrojs/telemetry, @astrojs/underscore-redirects, @astrojs/vercel, @astrojs/vue, @benchmark/timer, astro, create-astro�[0m �[2m• Running�[0m �[2m�[1mbuild�[0m�[0m �[2min 26 packages�[0m �[2m• Remote caching enabled�[0m ::group::@astrojs/prism:build cache hit, suppressing logs �[2m1fbe4acc344b9100�[0m ::endgroup:: ::group::@astrojs/telemetry:build cache hit, suppressing logs �[2m8f791e5bb7108651�[0m ::endgroup:: ::group::create-astro:build cache hit, suppressing logs �[2mb92067e8d3d6f572�[0m ::endgroup:: ::group::@astrojs/internal-helpers:build cache hit, suppressing logs �[2mc6ad1a8f27dca66f�[0m ::endgroup:: ::group::@astrojs/markdown-remark:build cache hit, suppressing logs �[2m5ea7eda930ba6d10�[0m ::endgroup:: ::group::astro:build cache miss, executing �[2m10c616d4ce501ac9�[0m > astro@0.0.0-concurrent-assets-20231015222920 build /home/runner/work/astro/astro/packages/astro > pnpm run prebuild && astro-scripts build "src/**/*.{ts,js}" && tsc && pnpm run postbuild > astro@0.0.0-concurrent-assets-20231015222920 prebuild /home/runner/work/astro/astro/packages/astro > astro-scripts prebuild --to-string "src/runtime/server/astro-island.ts" "src/runtime/client/{idle,load,media,only,visible}.ts" > astro@0.0.0-concurrent-assets-20231015222920 postbuild /home/runner/work/astro/astro/packages/astro > astro-scripts copy "src/**/*.astro" && astro-scripts copy "src/**/*.wasm" ::endgroup:: ::group::@astrojs/lit:build cache miss, executing �[2mab9119f8bee4df52�[0m > @astrojs/lit@3.0.1 build /home/runner/work/astro/astro/packages/integrations/lit > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@benchmark/timer:build cache miss, executing �[2m15907870e0dc29cd�[0m > @benchmark/timer@0.0.0 build /home/runner/work/astro/astro/benchmark/packages/timer > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/tailwind:build cache miss, executing �[2m350d0270a740e5ee�[0m > @astrojs/tailwind@5.0.2 build /home/runner/work/astro/astro/packages/integrations/tailwind > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/partytown:build cache miss, executing �[2m6bc2c216b2f06e0d�[0m > @astrojs/partytown@2.0.1 build /home/runner/work/astro/astro/packages/integrations/partytown > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/rss:build cache miss, executing �[2mf9580b113b248d13�[0m > @astrojs/rss@3.0.0 build /home/runner/work/astro/astro/packages/astro-rss > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/prefetch:build cache miss, executing �[2m286b801a034f7ce6�[0m > @astrojs/prefetch@0.4.1 build /home/runner/work/astro/astro/packages/integrations/prefetch > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/solid-js:build cache miss, executing �[2mf68dacf487532303�[0m > @astrojs/solid-js@3.0.2 build /home/runner/work/astro/astro/packages/integrations/solid > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/node:build cache miss, executing �[2m7d255646f6e26c76�[0m > @astrojs/node@6.0.3 build /home/runner/work/astro/astro/packages/integrations/node > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/svelte:build cache miss, executing �[2m59621156262c928a�[0m > @astrojs/svelte@4.0.3 build /home/runner/work/astro/astro/packages/integrations/svelte > astro-scripts build "src/index.ts" && astro-scripts build "src/editor.cts" --force-cjs --no-clean-dist && tsc ::endgroup:: ::group::@astrojs/vue:build cache miss, executing �[2mff8784e616a7cb61�[0m > @astrojs/vue@3.0.1 build /home/runner/work/astro/astro/packages/integrations/vue > astro-scripts build "src/index.ts" && astro-scripts build "src/editor.cts" --force-cjs --no-clean-dist && tsc ::endgroup:: ::group::@astrojs/underscore-redirects:build cache miss, executing �[2mf932a099dd7500bf�[0m > @astrojs/underscore-redirects@0.3.1 build /home/runner/work/astro/astro/packages/underscore-redirects > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json ::endgroup:: ::group::@astrojs/alpinejs:build cache miss, executing �[2ma8538a70270ad246�[0m > @astrojs/alpinejs@0.3.1 build /home/runner/work/astro/astro/packages/integrations/alpinejs > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/react:build cache miss, executing �[2m20d707f5a3c2bc9a�[0m > @astrojs/react@3.0.3 build /home/runner/work/astro/astro/packages/integrations/react > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/preact:build cache miss, executing �[2mc9aaaa5155ed5b5c�[0m > @astrojs/preact@3.0.1 build /home/runner/work/astro/astro/packages/integrations/preact > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/mdx:build cache miss, executing �[2m79a30f9be9be7ac3�[0m > @astrojs/mdx@1.1.2 build /home/runner/work/astro/astro/packages/integrations/mdx > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/vercel:build cache miss, executing �[2m727ed520e18b4ca1�[0m > @astrojs/vercel@5.0.2 build /home/runner/work/astro/astro/packages/integrations/vercel > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/markdoc:build cache miss, executing �[2m87dce92c0621f9a1�[0m > @astrojs/markdoc@0.6.0 build /home/runner/work/astro/astro/packages/integrations/markdoc > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/sitemap:build cache miss, executing �[2mc6654c70024d3a51�[0m > @astrojs/sitemap@3.0.1 build /home/runner/work/astro/astro/packages/integrations/sitemap > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: ::group::@astrojs/cloudflare:build cache miss, executing �[2mf91ee8d41e6dbc5b�[0m > @astrojs/cloudflare@7.5.3 build /home/runner/work/astro/astro/packages/integrations/cloudflare > astro-scripts build "src/**/*.ts" && tsc ::endgroup:: Tasks: 25 successful, 25 total Cached: 5 cached, 25 total Time: 1m8.064s 🦋 �[33mwarn�[39m �[31m===============================IMPORTANT!===============================�[39m 🦋 �[33mwarn�[39m Packages will be released under the next--concurrent-assets tag 🦋 �[33mwarn�[39m �[31m----------------------------------------------------------------------�[39m 🦋 �[36minfo�[39m npm info astro 🦋 �[36minfo�[39m npm info @astrojs/prism 🦋 �[36minfo�[39m npm info @astrojs/rss 🦋 �[36minfo�[39m npm info create-astro 🦋 �[36minfo�[39m npm info @astrojs/alpinejs 🦋 �[36minfo�[39m npm info @astrojs/cloudflare 🦋 �[36minfo�[39m npm info @astrojs/lit 🦋 �[36minfo�[39m npm info @astrojs/markdoc 🦋 �[36minfo�[39m npm info @astrojs/mdx 🦋 �[36minfo�[39m npm info @astrojs/node 🦋 �[36minfo�[39m npm info @astrojs/partytown 🦋 �[36minfo�[39m npm info @astrojs/preact 🦋 �[36minfo�[39m npm info @astrojs/prefetch 🦋 �[36minfo�[39m npm info @astrojs/react 🦋 �[36minfo�[39m npm info @astrojs/sitemap 🦋 �[36minfo�[39m npm info @astrojs/solid-js 🦋 �[36minfo�[39m npm info @astrojs/svelte 🦋 �[36minfo�[39m npm info @astrojs/tailwind 🦋 �[36minfo�[39m npm info @astrojs/vercel 🦋 �[36minfo�[39m npm info @astrojs/vue 🦋 �[36minfo�[39m npm info @astrojs/internal-helpers 🦋 �[36minfo�[39m npm info @astrojs/markdown-remark 🦋 �[36minfo�[39m npm info @astrojs/telemetry 🦋 �[36minfo�[39m npm info @astrojs/underscore-redirects 🦋 �[36minfo�[39m astro is being published because our local version (0.0.0-concurrent-assets-20231015222920) has not been published on npm 🦋 �[33mwarn�[39m @astrojs/prism is not being published because version 3.0.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/rss is not being published because version 3.0.0 is already published on npm 🦋 �[33mwarn�[39m create-astro is not being published because version 4.2.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/alpinejs is not being published because version 0.3.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/cloudflare is not being published because version 7.5.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/lit is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/markdoc is not being published because version 0.6.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/mdx is not being published because version 1.1.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/node is not being published because version 6.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/partytown is not being published because version 2.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/preact is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/prefetch is not being published because version 0.4.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/react is not being published because version 3.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/sitemap is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/solid-js is not being published because version 3.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/svelte is not being published because version 4.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/tailwind is not being published because version 5.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/vercel is not being published because version 5.0.2 is already published on npm 🦋 �[33mwarn�[39m @astrojs/vue is not being published because version 3.0.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/internal-helpers is not being published because version 0.2.1 is already published on npm 🦋 �[33mwarn�[39m @astrojs/markdown-remark is not being published because version 3.3.0 is already published on npm 🦋 �[33mwarn�[39m @astrojs/telemetry is not being published because version 3.0.3 is already published on npm 🦋 �[33mwarn�[39m @astrojs/underscore-redirects is not being published because version 0.3.1 is already published on npm 🦋 �[36minfo�[39m Publishing �[36m"astro"�[39m at �[32m"0.0.0-concurrent-assets-20231015222920"�[39m 🦋 �[32msuccess�[39m packages published successfully: 🦋 astro@0.0.0-concurrent-assets-20231015222920 🦋 Creating git tag... 🦋 New tag: astro@0.0.0-concurrent-assets-20231015222920

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some tests with remote images? Especially with the expiration part. It would be great if we could log the user when an image is not used anymore in case it's expired.

.changeset/good-mirrors-bake.md Outdated Show resolved Hide resolved
env: AssetEnv,
queue: PQueue
) {
const originalImageData = await loadImage(originalFilePath, env);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should apply your suggestions, probably in a follow-up PR. An I/O operation is usually more expensive than a memory operation, and even though Node.js is really great in I/O operations, I think we should try to avoid them if we can.

packages/astro/src/assets/build/generate.ts Outdated Show resolved Hide resolved
packages/astro/src/assets/build/generate.ts Outdated Show resolved Hide resolved
packages/astro/src/assets/build/generate.ts Show resolved Hide resolved
packages/astro/src/assets/build/generate.ts Show resolved Hide resolved
packages/astro/src/assets/build/generate.ts Show resolved Hide resolved
packages/astro/src/assets/build/generate.ts Show resolved Hide resolved
packages/astro/src/core/build/generate.ts Show resolved Hide resolved
@Princesseuh
Copy link
Member Author

Can we add some tests with remote images? Especially with the expiration part. It would be great if we could log the user when an image is not used anymore in case it's expired.

We have tests with remote images, both cached and uncached ones! We also have tests for errors specific to remote images etc.

Copy link
Member

@bluwy bluwy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I made os lower case)

🎉

@itsmatteomanf
Copy link
Contributor

@Princesseuh not sure where the delays are, but the cached builds are definitely slower than before... the un-cached ones are incredibly fast in comparison, but the cached builds aren't that much faster than uncached now.

@Princesseuh
Copy link
Member Author

@Princesseuh not sure where the delays are, but the cached builds are definitely slower than before... the un-cached ones are incredibly fast in comparison, but the cached builds aren't that much faster than uncached now.

It's a mix of multiple things

For local images on a fast hard drive, there's probably no big differences between this PR and main, but remote images suffer a bit more, I'll fix it

@itsmatteomanf
Copy link
Contributor

It's a mix of multiple things

It's somewhat baffling to me though, adding concurrency doesn't only not improve the performance (for what is basically the same process as the uncached images, just without the fetch, which is basically what has always been done and not much different bar the actual copying to what local images do), but slows it down by almost an order of magnitude... there must be something tiny somewhere that causes this.

I'll fix it.

I have no doubts about that ahah

Copy link
Member

@natemoo-re natemoo-re left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed during today's standup, I'm totally comfortable with the tradeoff being made here! Approved.

Uncached build are an order-of-magnitude, while cached builds seem to be slightly slower in some cases. Hopefully that can be improved in a follow-up, but this is still worth it.

@github-actions github-actions bot added the pr: docs A PR that includes documentation for review label Oct 25, 2023
Copy link
Member

@sarah11918 sarah11918 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Since it's a minor, just tried to get a jump on the blog post format with the suggestion below. (And tiny tweaks)

.changeset/good-mirrors-bake.md Outdated Show resolved Hide resolved
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is blocked because it contains a minor changeset. A reviewer will merge this at the next release if approved.

@Princesseuh Princesseuh dismissed GitHub Actions’s stale review October 25, 2023 12:03

It's merge day, once again

@Princesseuh Princesseuh merged commit 4740d76 into main Oct 25, 2023
13 checks passed
@Princesseuh Princesseuh deleted the assets-generate-concurrency branch October 25, 2023 12:21
@astrobot-houston astrobot-houston mentioned this pull request Oct 25, 2023
natemoo-re pushed a commit that referenced this pull request Nov 22, 2023
* feat: implement concurrency for asset generation

* add changeset

* fix: count

* feat: rework image generation to reuse image buffer for transforms of the same image

* fix: assetsPrefix nonsense

* feat: add back the counter

* refactor: cleanup my TS nonsense

* nit: reuse type

* nit: apply suggestions

* nit: macOS micro optimization

* Update .changeset/good-mirrors-bake.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

---------

Co-authored-by: Matteo Manfredi <matteo@manfredi.io>
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope) pr: docs A PR that includes documentation for review semver: minor Change triggers a `minor` release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants