diff --git a/.github/ISSUE_TEMPLATE/02-utils_bug_report.yml b/.github/ISSUE_TEMPLATE/02-utils_bug_report.yml index b067bdf..4b220b6 100644 --- a/.github/ISSUE_TEMPLATE/02-utils_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/02-utils_bug_report.yml @@ -13,7 +13,6 @@ body: attributes: label: Which utils is this bug report for? options: - - actions - eslint-config - prettier-config - other diff --git a/.github/ISSUE_TEMPLATE/03-feature_request.yml b/.github/ISSUE_TEMPLATE/03-feature_request.yml index 738de19..595f0d0 100644 --- a/.github/ISSUE_TEMPLATE/03-feature_request.yml +++ b/.github/ISSUE_TEMPLATE/03-feature_request.yml @@ -24,7 +24,6 @@ body: - network-client - network-server - sound - - actions - eslint-config - prettier-config - other diff --git a/.github/issue-labeler.yml b/.github/issue-labeler.yml index 89f86e0..2cb3258 100644 --- a/.github/issue-labeler.yml +++ b/.github/issue-labeler.yml @@ -50,10 +50,6 @@ packages:sound: - "### Which (package|utils|package or utils) is this (bug report|feature request) for\\?\\n\\nsound\\n" -utils:actions: - - "### Which (package|utils|package or utils) is this (bug - report|feature request) for\\?\\n\\nactions\\n" - utils:eslint-config: - "### Which (package|utils|package or utils) is this (bug report|feature request) for\\?\\n\\neslint-config\\n" diff --git a/.github/labeler.yml b/.github/labeler.yml index 5543403..dc173cc 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -76,12 +76,6 @@ packages:sound: - packages/sound/* - packages/sound/**/* -utils:actions: - - changed-files: - - any-glob-to-any-file: - - utils/actions/* - - utils/actions/**/* - utils:eslint-config: - changed-files: - any-glob-to-any-file: diff --git a/.github/labels.yml b/.github/labels.yml index 55bc3f7..3ff8359 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -102,10 +102,6 @@ description: "Adding missing tests or correcting existing tests" color: "7f8f92" -- name: "utils:actions" - description: "Related to Github actions" - color: "606bdf" - - name: "utils:eslint-config" description: "Related to ESLint config" color: "606bdf" diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index ae1a34b..8470d57 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -8,7 +8,6 @@ on: type: choice required: true options: - - "@nanoforge-dev/actions" - "@nanoforge-dev/asset-manager" - "@nanoforge-dev/common" - "@nanoforge-dev/config" @@ -26,9 +25,9 @@ on: - "@nanoforge-dev/utils-eslint-config" - "@nanoforge-dev/utils-prettier-config" version: - description: "New version of the package (leave empty for auto generated version)" + description: "New version of the package" type: string - required: false + required: true dry_run: description: Perform a dry run? type: boolean @@ -36,6 +35,7 @@ on: permissions: contents: write + pull-requests: write jobs: create-release-pr: @@ -45,12 +45,15 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true - name: Prepare uses: ./.github/actions/prepare - name: Release packages - uses: ./utils/actions/dist/create-release-pr + uses: ./node_modules/@nanoforge-dev/actions/dist/create-release-pr with: package: ${{ inputs.package }} version: ${{ inputs.version }} diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index fa9f1c2..1e631d1 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -1,4 +1,4 @@ -name: Release +name: Release Tag on: pull_request: @@ -23,7 +23,7 @@ jobs: uses: ./.github/actions/prepare - name: Create release tag - uses: ./utils/actions/dist/create-release-tag + uses: ./node_modules/@nanoforge-dev/actions/dist/create-release-tag with: commit: ${{ github.sha }} branch: ${{ github.head_ref }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97a6393..dd969f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,6 @@ on: required: false options: - "all" - - "@nanoforge-dev/actions" - "@nanoforge-dev/asset-manager" - "@nanoforge-dev/common" - "@nanoforge-dev/config" @@ -51,7 +50,7 @@ jobs: uses: ./.github/actions/prepare - name: Release packages - uses: ./utils/actions/dist/release-packages + uses: ./node_modules/@nanoforge-dev/actions/dist/release-packages with: package: ${{ inputs.package }} exclude: ${{ inputs.exclude }} diff --git a/package.json b/package.json index a95cadc..1f5c271 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,7 @@ "type": "module", "repository": { "type": "git", - "url": "git+https://github.com/NanoForge-dev/Engine.git", - "directory": "packages/ecs" + "url": "git+https://github.com/NanoForge-dev/Engine.git" }, "funding": "https://github.com/NanoForge-dev/Engine?sponsor", "scripts": { @@ -33,6 +32,7 @@ "devDependencies": { "@commitlint/cli": "^20.1.0", "@commitlint/config-conventional": "^20.0.0", + "@nanoforge-dev/actions": "^1.1.0", "@nanoforge-dev/utils-eslint-config": "workspace:^", "@nanoforge-dev/utils-prettier-config": "workspace:^", "@trivago/prettier-plugin-sort-imports": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index becfd0e..d2f405e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,6 +18,9 @@ importers: '@commitlint/config-conventional': specifier: ^20.0.0 version: 20.2.0 + '@nanoforge-dev/actions': + specifier: ^1.1.0 + version: 1.1.0 '@nanoforge-dev/utils-eslint-config': specifier: workspace:^ version: link:utils/eslint-config @@ -541,52 +544,6 @@ importers: specifier: ^5.9.3 version: 5.9.3 - utils/actions: - dependencies: - '@actions/core': - specifier: ^2.0.1 - version: 2.0.1 - '@actions/github': - specifier: ^6.0.1 - version: 6.0.1 - commander: - specifier: ^14.0.2 - version: 14.0.2 - devDependencies: - '@favware/cliff-jumper': - specifier: ^6.0.0 - version: 6.0.0 - '@nanoforge-dev/utils-eslint-config': - specifier: workspace:^ - version: link:../eslint-config - '@nanoforge-dev/utils-prettier-config': - specifier: workspace:^ - version: link:../prettier-config - '@npm/types': - specifier: ^2.1.0 - version: 2.1.0 - '@trivago/prettier-plugin-sort-imports': - specifier: ^6.0.0 - version: 6.0.0(prettier@3.7.4) - '@types/bun': - specifier: ^1.3.5 - version: 1.3.5 - eslint: - specifier: ^9.39.1 - version: 9.39.1(jiti@2.6.1) - prettier: - specifier: ^3.6.2 - version: 3.7.4 - terser: - specifier: ^5.44.1 - version: 5.44.1 - tsup: - specifier: ^8.5.1 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.8.2) - typescript: - specifier: ^5.9.3 - version: 5.9.3 - utils/eslint-config: dependencies: '@eslint/js': @@ -641,17 +598,14 @@ importers: packages: - '@actions/core@2.0.1': - resolution: {integrity: sha512-oBfqT3GwkvLlo1fjvhQLQxuwZCGTarTE5OuZ2Wg10hvhBj7LRIlF611WT4aZS6fDhO5ZKlY7lCAZTlpmyaHaeg==} + '@actions/core@2.0.2': + resolution: {integrity: sha512-Ast1V7yHbGAhplAsuVlnb/5J8Mtr/Zl6byPPL+Qjq3lmfIgWF1ak1iYfF/079cRERiuTALTXkSuEUdZeDCfGtA==} '@actions/exec@2.0.0': resolution: {integrity: sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw==} - '@actions/github@6.0.1': - resolution: {integrity: sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==} - - '@actions/http-client@2.2.3': - resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} + '@actions/github@7.0.0': + resolution: {integrity: sha512-PyGODO938aoBTZd/IfN/+e+Pd5hUcVpyf+thm4CPESLeqhdSkq5QwMTGX9v84XHE1ifmHWBQ60KB8kIgm96opw==} '@actions/http-client@3.0.1': resolution: {integrity: sha512-SbGS8c/vySbNO3kjFgSW77n83C4MQx/Yoe+b1hAdpuvfHxnkHzDq2pWljUpAA56Si1Gae/7zjeZsV0CYjmLo/w==} @@ -1197,9 +1151,9 @@ packages: engines: {node: '>=18'} hasBin: true - '@npm/types@2.1.0': - resolution: {integrity: sha512-humQVe2BrWR7Yum5hGDYBnIPnnZJvKSOH/I4QN1ZL2bdb4c4zQHaHupEJ3cOkSJ07G3YfN793ptbNh196BWLgA==} - engines: {node: '>=18.6.0'} + '@nanoforge-dev/actions@1.1.0': + resolution: {integrity: sha512-BTZyJ69Ax5nvMYqFRzj4WGvFTUW4W9JSDSaln4DwJmDtS3davkwphuXS85WEghQ1lpbp+gHuOUXu6Xj56gwW2w==} + engines: {node: '25'} '@octokit/auth-token@4.0.0': resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} @@ -1451,9 +1405,6 @@ packages: svelte: optional: true - '@types/bun@1.3.5': - resolution: {integrity: sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w==} - '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -1676,9 +1627,6 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - bun-types@1.3.5: - resolution: {integrity: sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw==} - bundle-require@5.1.0: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3081,7 +3029,7 @@ packages: snapshots: - '@actions/core@2.0.1': + '@actions/core@2.0.2': dependencies: '@actions/exec': 2.0.0 '@actions/http-client': 3.0.1 @@ -3090,9 +3038,9 @@ snapshots: dependencies: '@actions/io': 2.0.0 - '@actions/github@6.0.1': + '@actions/github@7.0.0': dependencies: - '@actions/http-client': 2.2.3 + '@actions/http-client': 3.0.1 '@octokit/core': 5.2.2 '@octokit/plugin-paginate-rest': 9.2.2(@octokit/core@5.2.2) '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.2) @@ -3100,11 +3048,6 @@ snapshots: '@octokit/request-error': 5.1.1 undici: 5.29.0 - '@actions/http-client@2.2.3': - dependencies: - tunnel: 0.0.6 - undici: 5.29.0 - '@actions/http-client@3.0.1': dependencies: tunnel: 0.0.6 @@ -3544,6 +3487,7 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + optional: true '@jridgewell/sourcemap-codec@1.5.5': {} @@ -3565,7 +3509,11 @@ snapshots: - encoding - supports-color - '@npm/types@2.1.0': {} + '@nanoforge-dev/actions@1.1.0': + dependencies: + '@actions/core': 2.0.2 + '@actions/github': 7.0.0 + commander: 14.0.2 '@octokit/auth-token@4.0.0': {} @@ -3785,10 +3733,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@types/bun@1.3.5': - dependencies: - bun-types: 1.3.5 - '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 @@ -4052,11 +3996,8 @@ snapshots: dependencies: fill-range: 7.1.1 - buffer-from@1.1.2: {} - - bun-types@1.3.5: - dependencies: - '@types/node': 24.10.2 + buffer-from@1.1.2: + optional: true bundle-require@5.1.0(esbuild@0.27.1): dependencies: @@ -4117,7 +4058,8 @@ snapshots: commander@14.0.2: {} - commander@2.20.3: {} + commander@2.20.3: + optional: true commander@4.1.1: {} @@ -5001,8 +4943,10 @@ snapshots: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 + optional: true - source-map@0.6.1: {} + source-map@0.6.1: + optional: true source-map@0.7.6: {} @@ -5082,6 +5026,7 @@ snapshots: acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 + optional: true text-extensions@2.4.0: {} diff --git a/utils/actions/.cliff-jumperrc.json b/utils/actions/.cliff-jumperrc.json deleted file mode 100644 index 2461b0b..0000000 --- a/utils/actions/.cliff-jumperrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/favware/cliff-jumper/main/assets/cliff-jumper.schema.json", - "name": "actions", - "org": "nanoforge-dev", - "packagePath": "utils/actions", - "identifierBase": false -} diff --git a/utils/actions/.gitignore b/utils/actions/.gitignore deleted file mode 100644 index f7652f8..0000000 --- a/utils/actions/.gitignore +++ /dev/null @@ -1,231 +0,0 @@ -### VisualStudioCode template -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -!.vscode/*.code-snippets - -# Local History for Visual Studio Code -.history/ - -# Built Visual Studio Code Extensions -*.vsix - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# AWS User-specific -.idea/**/aws.xml - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# SonarLint plugin -.idea/sonarlint/ - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Node template -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - -# Turbo -.turbo/ - -# Compiled files -src/**/*.js -src/**/*.d.ts diff --git a/utils/actions/.nvmrc b/utils/actions/.nvmrc deleted file mode 100644 index c519bf5..0000000 --- a/utils/actions/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v24.11.0 diff --git a/utils/actions/.prettierignore b/utils/actions/.prettierignore deleted file mode 100644 index 64b127c..0000000 --- a/utils/actions/.prettierignore +++ /dev/null @@ -1,11 +0,0 @@ -# Ignore files for PNPM, NPM and YARN -pnpm-lock.yaml -package-lock.json -yarn.lock -bun.lock - -.turbo/ -node_modules/ -dist/ -coverage/ -CHANGELOG.md diff --git a/utils/actions/CHANGELOG.md b/utils/actions/CHANGELOG.md deleted file mode 100644 index f159afa..0000000 --- a/utils/actions/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -# [@nanoforge-dev/actions@1.0.2](https://github.com/NanoForge-dev/Engine/compare/@nanoforge-dev/actions@1.0.1...@nanoforge-dev/actions@1.0.2) - (2026-01-10) - -## Bug Fixes - -- **actions:** Change release process to fit with new actions (#183) ([3016d45](https://github.com/NanoForge-dev/Engine/commit/3016d45b41a7f8bbd16962cb5f7aea956f84bde3)) by @Exeloo -- **actions:** Change compilation to handle usage of actions from other repositories (#182) ([31a9514](https://github.com/NanoForge-dev/Engine/commit/31a951416c44301e5784b51bcfaff7fc49f176c8)) by @Exeloo - -# [@nanoforge-dev/actions@1.0.1](https://github.com/NanoForge-dev/Engine/compare/@nanoforge-dev/actions@1.0.0...@nanoforge-dev/actions@1.0.1) - (2026-01-09) - -## Bug Fixes - -- Add permissions to ci and change release process (#179) ([91b8832](https://github.com/NanoForge-dev/Engine/commit/91b88329d61fd96305c5868d39589439cfa08814)) by @Exeloo - -# [@nanoforge-dev/actions@1.0.0](https://github.com/NanoForge-dev/Engine/tree/@nanoforge-dev/actions@1.0.0) - (2026-01-09) - -## CI - -- Add release ci (#164) ([7e771e5f](https://github.com/NanoForge-dev/Engine/commit/7e771e5fac06fe3b1b4ecf45d99fa8432a8a02ee)) by @Exeloo - diff --git a/utils/actions/LICENSE b/utils/actions/LICENSE deleted file mode 100644 index 4672486..0000000 --- a/utils/actions/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright © 2026 NanoForge - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/utils/actions/README.md b/utils/actions/README.md deleted file mode 100644 index 1111cef..0000000 --- a/utils/actions/README.md +++ /dev/null @@ -1,54 +0,0 @@ -
-
-

- NanoForge -

-
-

- npm version - npm downloads - Tests status - Documentation status - Last commit - Contributors -

-
- -## About - -`@nanoforge-dev/actions` is library that contains all utils for nanoforge actions. - -Most of the sources of this package come from [discord.js][discordjs-source]. Spetial thanks to them ! - -## Installation - -**Node.js 24.11.0 or newer is required.** - -```sh -npm install @nanoforge-dev/actions -yarn add @nanoforge-dev/actions -pnpm add @nanoforge-dev/actions -bun add @nanoforge-dev/actions -``` - -## Links - -- [GitHub][source] -- [npm][npm] - -## Contributing - -Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the -[documentation][documentation]. -See [the contribution guide][contributing] if you'd like to submit a PR. - -## Help - -If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle nudge in the right direction, please don't hesitate to ask questions in [discussions][discussions]. - -[documentation]: https://github.com/NanoForge-dev/Engine -[discussions]: https://github.com/NanoForge-dev/Engine/discussions -[source]: https://github.com/NanoForge-dev/Engine/tree/main/packages/actions -[npm]: https://www.npmjs.com/package/@nanoforge-dev/actions -[contributing]: https://github.com/NanoForge-dev/Engine/blob/main/.github/CONTRIBUTING.md -[discordjs-source]: https://github.com/discordjs/discord.js diff --git a/utils/actions/cliff.toml b/utils/actions/cliff.toml deleted file mode 100644 index 21fe47a..0000000 --- a/utils/actions/cliff.toml +++ /dev/null @@ -1,79 +0,0 @@ -[changelog] -header = """ -# Changelog - -All notable changes to this project will be documented in this file.\n -""" -body = """ -{%- macro remote_url() -%} - https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} -{%- endmacro -%} -{% if version %}\ - # [{{ version | trim_start_matches(pat="v") }}]\ - {% if previous %}\ - {% if previous.version %}\ - ({{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }})\ - {% else %}\ - ({{ self::remote_url() }}/tree/{{ version }})\ - {% endif %}\ - {% endif %} \ - - ({{ timestamp | date(format="%Y-%m-%d") }}) -{% else %}\ - # [unreleased] -{% endif %}\ -{% for group, commits in commits | group_by(attribute="group") %} - ## {{ group | upper_first }} - {% for commit in commits %} - - {% if commit.scope %}\ - **{{commit.scope}}:** \ - {% endif %}\ - {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\ - {% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\ - {% if commit.breaking %}\ - {% for footer in commit.footers %}\ - {% if footer.breaking %}\ - \n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\ - {% endif %}\ - {% endfor %}\ - {% endif %}\ - {% endfor %} -{% endfor %}\ -{% if github.contributors | filter(attribute="is_first_time", value=true) | length %}\ - \n### New Contributors\n - {% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}\ - - @{{ contributor.username }} made their first contribution in #{{ contributor.pr_number }} - {% endfor %}\ -{% endif %}\n -""" -trim = true -footer = "" - -[git] -conventional_commits = true -filter_unconventional = true -commit_parsers = [ - { message = "^feat", group = "Features"}, - { message = "^fix", group = "Bug Fixes"}, - { message = "^docs", group = "Documentation"}, - { message = "^perf", group = "Performance"}, - { message = "^refactor", group = "Refactor"}, - { message = "^types", group = "Typings"}, - { message = ".*deprecated", body = ".*deprecated", group = "Deprecation"}, - { message = "^revert", skip = true}, - { message = "^style", group = "Styling"}, - { message = "^test", group = "Testing"}, - { message = "^chore", skip = true}, - { message = "^ci", skip = true}, - { message = "^build", skip = true}, - { body = ".*security", group = "Security"}, -] -filter_commits = true -protect_breaking_commits = true -tag_pattern = "@nanoforge-dev/actions@[0-9]*" -ignore_tags = "" -topo_order = false -sort_commits = "newest" - -[remote.github] -owner = "NanoForge-dev" -repo = "Engine" diff --git a/utils/actions/eslint.config.js b/utils/actions/eslint.config.js deleted file mode 100644 index 62ec06d..0000000 --- a/utils/actions/eslint.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from "@nanoforge-dev/utils-eslint-config"; - -export default config; diff --git a/utils/actions/package.json b/utils/actions/package.json deleted file mode 100644 index 1f8366f..0000000 --- a/utils/actions/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/package.json", - "name": "@nanoforge-dev/actions", - "version": "1.0.2", - "description": "NanoForge Engine - Actions", - "keywords": [ - "nanoforge", - "game", - "engine" - ], - "homepage": "https://github.com/NanoForge-dev/Engine#readme", - "bugs": "https://github.com/NanoForge-dev/Engine/issues", - "license": "MIT", - "contributors": [ - "Bill ", - "Exelo ", - "Fexkoser ", - "Tchips " - ], - "files": [ - "dist" - ], - "exports": { - "./package.json": "./package.json" - }, - "type": "module", - "directories": { - "lib": "src" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/NanoForge-dev/Engine.git", - "directory": "packages/actions" - }, - "funding": "https://github.com/NanoForge-dev/Engine?sponsor", - "scripts": { - "build": "tsc --noEmit && tsup", - "lint": "prettier --check . && eslint --format=pretty src", - "format": "prettier --write . && eslint --fix --format=pretty src", - "prepack": "pnpm run build && pnpm run lint", - "changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'utils/actions/*'", - "release": "cliff-jumper" - }, - "dependencies": { - "@actions/core": "^2.0.1", - "@actions/github": "^6.0.1", - "commander": "^14.0.2" - }, - "devDependencies": { - "@favware/cliff-jumper": "^6.0.0", - "@nanoforge-dev/utils-eslint-config": "workspace:^", - "@nanoforge-dev/utils-prettier-config": "workspace:^", - "@npm/types": "^2.1.0", - "@trivago/prettier-plugin-sort-imports": "^6.0.0", - "@types/bun": "^1.3.5", - "eslint": "^9.39.1", - "prettier": "^3.6.2", - "terser": "^5.44.1", - "tsup": "^8.5.1", - "typescript": "^5.9.3" - }, - "packageManager": "pnpm@10.22.0", - "engines": { - "node": "24.11.0" - }, - "publishConfig": { - "access": "public" - }, - "lint-staged": { - "**/*.ts": [ - "prettier --write" - ], - "src/**/*.ts": [ - "eslint --fix" - ] - } -} diff --git a/utils/actions/prettier.config.js b/utils/actions/prettier.config.js deleted file mode 100644 index 27d0e26..0000000 --- a/utils/actions/prettier.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from "@nanoforge-dev/utils-prettier-config"; - -export default config; diff --git a/utils/actions/src/create-release-pr/action.yml b/utils/actions/src/create-release-pr/action.yml deleted file mode 100644 index 7e092f1..0000000 --- a/utils/actions/src/create-release-pr/action.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: "Create release PR" -description: "Create a PR for releasing a package" -inputs: - dry: - description: "Perform a dry run that skips pr creation and outputs logs indicating what would have happened" - default: "false" - package: - description: "The published name of the package to release" - version: - description: "New version of the package" -runs: - using: composite - steps: - - uses: oven-sh/setup-bun@v2 - - run: bun $GITHUB_ACTION_PATH/index.js - shell: bash - env: - INPUT_DRY: ${{ inputs.dry }} - INPUT_PACKAGE: ${{ inputs.package }} - INPUT_VERSION: ${{ inputs.version }} diff --git a/utils/actions/src/create-release-pr/functions.ts b/utils/actions/src/create-release-pr/functions.ts deleted file mode 100644 index 86a073a..0000000 --- a/utils/actions/src/create-release-pr/functions.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { context, getOctokit } from "@actions/github"; -import { $, file, write } from "bun"; -import process from "node:process"; -import { join } from "path"; - -import { type IPkg } from "./types"; - -let octokit: ReturnType | undefined; - -if (process.env.GITHUB_TOKEN) { - octokit = getOctokit(process.env.GITHUB_TOKEN); -} - -export const resolvePackage = async (name: string): Promise => { - const pkgs: IPkg[] = - await $`pnpm list --filter ${name} --recursive --only-projects --prod --json`.json(); - if (pkgs.length <= 0) throw new Error("Package not found"); - return pkgs[0] as IPkg; -}; - -export const resolveChangelog = async ( - path: string, - name: string, - version: string, -): Promise => { - const changelogFile = await file(join(path, "CHANGELOG.md")).text(); - let changelogLines: string[] = []; - let foundChangelog = false; - - for (const line of changelogFile.split("\n")) { - if (line.startsWith("# [")) { - if (foundChangelog) { - if (changelogLines.at(-1) === "") changelogLines = changelogLines.slice(2, -1); - break; - } - if (!line.startsWith(`# [${name}@${version}]`)) break; - foundChangelog = true; - } - if (foundChangelog) changelogLines.push(line); - } - - return `${changelogLines.join("\n").replace(/^\s+|\s+$/g, "")}\n`; -}; - -export const resolveVersion = async (name: string): Promise => { - const regex = new RegExp(`^📦 Bumped ${name}@(\\d+\\.\\d+\\.\\d+)$`); - const res = await $`pnpm --filter=${name} run release --dry-run`.text(); - for (const line of res.split("\n")) { - const match = regex.exec(line); - if (match) return match[1] as string; - } - throw new Error("Could not find the version"); -}; - -export const checkoutToReleaseBranch = async (name: string, version: string): Promise => { - const branchName = `releases/${name.replace("@nanoforge-dev/", "")}@${version}`; - await $`git checkout -b ${branchName}`; - return branchName; -}; - -export const updateVersion = async (path: string, version: string): Promise => { - const fullPath = join(path, "package.json"); - const pkg = await file(fullPath).json(); - pkg.version = version; - await write(fullPath, JSON.stringify(pkg)); -}; - -export const runRelease = async (name: string): Promise => { - await $`pnpm --filter=${name} run release --skip-automatic-bump --skip-tag`; -}; - -export const pushRelease = async (branch: string): Promise => { - await $`git push origin refs/heads/${branch}:${branch}`; -}; - -export const createPR = async (branchName: string): Promise => { - await octokit?.rest.pulls.create({ - ...context.repo, - base: "main", - head: branchName, - title: await $`git show -s --format=%s`.text(), - }); -}; diff --git a/utils/actions/src/create-release-pr/index.ts b/utils/actions/src/create-release-pr/index.ts deleted file mode 100644 index 2655b3b..0000000 --- a/utils/actions/src/create-release-pr/index.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { getBooleanInput, getInput, summary } from "@actions/core"; -import { program } from "commander"; - -import { - checkoutToReleaseBranch, - createPR, - pushRelease, - resolveChangelog, - resolvePackage, - resolveVersion, - runRelease, - updateVersion, -} from "./functions"; - -const createSummary = async (name: string, dry: boolean) => { - const pkg = await resolvePackage(name); - const changelog = await resolveChangelog(pkg.path, pkg.name, pkg.version); - - const result = summary.addHeading("Pre-Release summary"); - - if (dry) { - result.addRaw("\n\n> [!NOTE]\n> This is a dry run.\n\n"); - } - - result.addHeading(`${pkg.name} pre-released`, 2); - - result.addRaw(`> Version : ${pkg.version}\n`); - result.addSeparator(); - result.addRaw("> Changelog :\n"); - result.addBreak(); - result.addCodeBlock(changelog); - - await result.write(); -}; - -const bootstrap = async () => { - program - .name("create release pr") - .description("pre-releases monorepo packages with proper sequencing") - .argument( - "[package]", - "release a specific package (and it's dependencies)", - getInput("package"), - ) - .option("--dry", "skips actual publishing and outputs logs instead", getBooleanInput("dry")) - .option("--version ", "new version of the package", getInput("version")) - .parse(); - - const { dry, version: baseVersion } = program.opts<{ dry: boolean; version: string }>(); - const [packageName] = program.processedArgs as [string]; - - const pkg = await resolvePackage(packageName); - const version = baseVersion || (await resolveVersion(packageName)); - - const branchName = await checkoutToReleaseBranch(pkg.name, version); - await updateVersion(pkg.path, version); - await runRelease(pkg.name); - if (!dry) { - await pushRelease(branchName); - await createPR(branchName); - } - - await createSummary(packageName, dry); -}; - -bootstrap().then(); diff --git a/utils/actions/src/create-release-pr/types.ts b/utils/actions/src/create-release-pr/types.ts deleted file mode 100644 index 370f19d..0000000 --- a/utils/actions/src/create-release-pr/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface IPkg { - name: string; - version: string; - path: string; - private: boolean; -} diff --git a/utils/actions/src/create-release-tag/action.yml b/utils/actions/src/create-release-tag/action.yml deleted file mode 100644 index fea0d64..0000000 --- a/utils/actions/src/create-release-tag/action.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: "Create release tag" -description: "Create a tag the package release" -inputs: - commit: - description: "Commit sha to put the tag on" - branch: - description: "Head branch name" -runs: - using: composite - steps: - - uses: oven-sh/setup-bun@v2 - - run: bun $GITHUB_ACTION_PATH/index.js - shell: bash - env: - INPUT_COMMIT: ${{ inputs.commit }} - INPUT_BRANCH: ${{ inputs.branch }} diff --git a/utils/actions/src/create-release-tag/index.ts b/utils/actions/src/create-release-tag/index.ts deleted file mode 100644 index e2d881a..0000000 --- a/utils/actions/src/create-release-tag/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { getInput } from "@actions/core"; -import { context, getOctokit } from "@actions/github"; -import { program } from "commander"; -import process from "node:process"; - -let octokit: ReturnType | undefined; - -if (process.env.GITHUB_TOKEN) { - octokit = getOctokit(process.env.GITHUB_TOKEN); -} - -const bootstrap = async () => { - program - .name("create release tag") - .description("create release tag for monorepo packages with proper sequencing") - .option("--commit ", "commit sha of ythe last commit", getInput("commit")) - .option("--branch ", "head branch of the merged pr", getInput("branch")) - .parse(); - - const { commit, branch } = program.opts<{ commit: string; branch: string }>(); - - const pkg = branch.replace("releases/", "@nanoforge-dev/"); - - await octokit?.rest.git.createRef({ - ...context.repo, - ref: `refs/tags/${pkg}`, - sha: commit, - }); -}; - -bootstrap().then(); diff --git a/utils/actions/src/release-packages/action.yml b/utils/actions/src/release-packages/action.yml deleted file mode 100644 index e95e9f8..0000000 --- a/utils/actions/src/release-packages/action.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: "Release Packages" -description: "Tags and releases any unreleased packages" -inputs: - dev: - description: "Releases development versions of packages (skips tagging and github releases)" - default: "false" - dry: - description: "Perform a dry run that skips publishing and outputs logs indicating what would have happened" - default: "false" - package: - description: "The published name of a single package to release" - exclude: - description: "Comma separated list of packages to exclude from release (if not depended upon)" - tag: - description: "The tag to use, generally a feature name" -runs: - using: composite - steps: - - uses: oven-sh/setup-bun@v2 - - run: bun $GITHUB_ACTION_PATH/index.js - shell: bash - env: - INPUT_DEV: ${{ inputs.dev }} - INPUT_DRY: ${{ inputs.dry }} - INPUT_PACKAGE: ${{ inputs.package }} - INPUT_EXCLUDE: ${{ inputs.exclude }} - INPUT_TAG: ${{ inputs.tag }} diff --git a/utils/actions/src/release-packages/generate-release-tree.ts b/utils/actions/src/release-packages/generate-release-tree.ts deleted file mode 100644 index f657cbc..0000000 --- a/utils/actions/src/release-packages/generate-release-tree.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { info, warning } from "@actions/core"; -import type { PackageJSON, PackumentVersion } from "@npm/types"; -import { $, file, write } from "bun"; - -interface pnpmTreeDependency { - from: string; - path: string; - version: string; -} - -interface pnpmTree { - dependencies?: Record; - name?: string; - path: string; - private?: boolean; - unsavedDependencies?: Record; - version?: string; -} - -export interface ReleaseEntry { - changelog?: string; - dependsOn?: string[]; - name: string; - version: string; -} - -async function fetchDevVersion(pkg: string, tag: string) { - try { - const res = await fetch(`https://registry.npmjs.org/${pkg}/${tag}`); - if (!res.ok) return null; - const packument = (await res.json()) as PackumentVersion; - return packument.version; - } catch { - return null; - } -} - -async function getReleaseEntries(dry: boolean, devTag?: string) { - const releaseEntries: ReleaseEntry[] = []; - const packageList: pnpmTree[] = - await $`pnpm list --recursive --only-projects --prod --json`.json(); - - const commitHash = (await $`git rev-parse --short HEAD`.text()).trim(); - const timestamp = Math.round(Date.now() / 1_000); - - for (const pkg of packageList) { - // Don't release private packages ever (npm will error anyways) - if (pkg.private) continue; - // Just in case - if (!pkg.version || !pkg.name) continue; - - const release: ReleaseEntry = { - name: pkg.name, - version: pkg.version, - }; - - if (devTag) { - // Replace workspace dependencies with * to pin to associated dev versions - if (!dry) { - const pkgJsonString = await file(`${pkg.path}/package.json`).text(); - await write( - `${pkg.path}/package.json`, - pkgJsonString.replaceAll(/workspace:[\^~]/g, "workspace:*"), - ); - } - - const devVersion = await fetchDevVersion(pkg.name, devTag); - if (devVersion?.endsWith(commitHash)) { - // Write the currently released dev version so when pnpm publish runs on dependents they depend on the dev versions - if (dry) { - info(`[DRY] ${pkg.name}@${devVersion} already released. Editing package.json version.`); - } else { - const pkgJson = (await file(`${pkg.path}/package.json`).json()) as PackageJSON; - pkgJson.version = devVersion; - await write(`${pkg.path}/package.json`, JSON.stringify(pkgJson, null, "\t")); - } - - release.version = devVersion; - } else if (dry) { - info(`[DRY] Bumping ${pkg.name} via git-cliff.`); - release.version = `${pkg.version}.DRY-${devTag}.${timestamp}-${commitHash}`; - } else { - await $`pnpm --filter=${pkg.name} run release --preid "${devTag}.${timestamp}-${commitHash}" --skip-changelog`; - // Read again instead of parsing the output to be sure we're matching when checking against npm - const pkgJson = (await file(`${pkg.path}/package.json`).json()) as PackageJSON; - release.version = pkgJson.version; - } - } - // Only need changelog for releases published to github - else { - try { - // Find and parse changelog to post in github release - const changelogFile = await file(`${pkg.path}/CHANGELOG.md`).text(); - - let changelogLines: string[] = []; - let foundChangelog = false; - - for (const line of changelogFile.split("\n")) { - if (line.startsWith("# [")) { - if (foundChangelog) { - if (changelogLines.at(-1) === "") { - changelogLines = changelogLines.slice(2, -1); - } - - break; - } - - // Check changelog release version and assume no changelog if version does not match - if (!line.startsWith(`# [${release.name}@${release.version}]`)) { - break; - } - - foundChangelog = true; - continue; - } - - if (foundChangelog) { - changelogLines.push(line); - } - } - - release.changelog = `${changelogLines.join("\n").replace(/^\s+|\s+$/g, "")}\n`; - } catch (error) { - // Probably just no changelog file but log just in case - warning(`Error parsing changelog for ${pkg.name}, will use auto generated: ${error}`); - } - } - - if (pkg.dependencies) { - release.dependsOn = Object.keys(pkg.dependencies); - } - - releaseEntries.push(release); - } - - return releaseEntries; -} - -export async function generateReleaseTree( - dry: boolean, - devTag?: string, - packageName?: string, - exclude?: string[], -) { - let releaseEntries = await getReleaseEntries(dry, devTag); - // Try to early return if the package doesn't have deps - if (packageName && packageName !== "all") { - const releaseEntry = releaseEntries.find((entry) => entry.name === packageName); - if (!releaseEntry) { - throw new Error(`Package ${packageName} not releaseable`); - } - - if (!releaseEntry.dependsOn) { - return [[releaseEntry]]; - } - } - - // Generate the whole tree first, then prune if specified - const releaseTree: ReleaseEntry[][] = []; - const didRelease = new Set(); - - while (releaseEntries.length) { - const nextBranch: ReleaseEntry[] = []; - const unreleased: ReleaseEntry[] = []; - for (const entry of releaseEntries) { - if (!entry.dependsOn) { - nextBranch.push(entry); - continue; - } - - const allDepsReleased = entry.dependsOn.every((dep) => didRelease.has(dep)); - if (allDepsReleased) { - nextBranch.push(entry); - } else { - unreleased.push(entry); - } - } - - // Update didRelease in a second loop to avoid loop order issues - for (const release of nextBranch) { - didRelease.add(release.name); - } - - if (releaseEntries.length === unreleased.length) { - throw new Error( - `One or more packages have dependents that can't be released: ${unreleased.map((entry) => entry.name).join(",")}`, - ); - } - - releaseTree.push(nextBranch); - releaseEntries = unreleased; - } - - // Prune exclusions - if ((!packageName || packageName === "all") && Array.isArray(exclude) && exclude.length) { - const neededPackages = new Set(); - const excludedReleaseTree: ReleaseEntry[][] = []; - - for (const releaseBranch of releaseTree.reverse()) { - const newThisBranch: ReleaseEntry[] = []; - - for (const entry of releaseBranch) { - if (exclude.includes(entry.name) && !neededPackages.has(entry.name)) { - continue; - } - - newThisBranch.push(entry); - for (const dep of entry.dependsOn ?? []) { - neededPackages.add(dep); - } - } - - if (newThisBranch.length) excludedReleaseTree.unshift(newThisBranch); - } - - return excludedReleaseTree; - } - - if (!packageName || packageName === "all") { - return releaseTree; - } - - // Prune the tree for the specified package - const neededPackages = new Set([packageName]); - const packageReleaseTree: ReleaseEntry[][] = []; - - for (const releaseBranch of releaseTree.reverse()) { - const newThisBranch: ReleaseEntry[] = []; - - for (const entry of releaseBranch) { - if (neededPackages.has(entry.name)) { - newThisBranch.push(entry); - for (const dep of entry.dependsOn ?? []) { - neededPackages.add(dep); - } - } - } - - if (newThisBranch.length) packageReleaseTree.unshift(newThisBranch); - } - - return packageReleaseTree; -} diff --git a/utils/actions/src/release-packages/index.ts b/utils/actions/src/release-packages/index.ts deleted file mode 100644 index 0703feb..0000000 --- a/utils/actions/src/release-packages/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { endGroup, getBooleanInput, getInput, startGroup, summary } from "@actions/core"; -import { program } from "commander"; - -import { generateReleaseTree } from "./generate-release-tree"; -import { releasePackage } from "./release-package"; - -function npmPackageLink(packageName: string) { - return `https://npmjs.com/package/${packageName}` as const; -} - -const excludeInput = getInput("exclude"); -let dryInput = false; -let devInput = false; - -try { - devInput = getBooleanInput("dev"); -} catch { - // We're not running in actions -} - -try { - dryInput = getBooleanInput("dry"); -} catch { - // We're not running in actions or the input isn't set (cron) -} - -program - .name("release packages") - .description("releases monorepo packages with proper sequencing") - .argument("[package]", "release a specific package (and it's dependencies)", getInput("package")) - .option( - "-e, --exclude ", - "exclude specific packages from releasing (will still release if necessary for another package)", - excludeInput ? excludeInput.split(",") : [], - ) - .option("--dry", "skips actual publishing and outputs logs instead", dryInput) - .option("--dev", "publishes development versions and skips tagging / github releases", devInput) - .option("--tag ", 'tag to use for dev releases (defaults to "dev")', getInput("tag")) - .parse(); - -const { - exclude, - dry, - dev, - tag: inputTag, -} = program.opts<{ dev: boolean; dry: boolean; exclude: string[]; tag: string }>(); - -// All this because getInput('tag') will return empty string when not set :P -if (!dev && inputTag.length) { - throw new Error("The --tag option can only be used with --dev"); -} - -const tag = inputTag.length ? inputTag : dev ? "dev" : undefined; -const [packageName] = program.processedArgs as [string]; -const tree = await generateReleaseTree(dry, tag, packageName, exclude); - -interface ReleaseResult { - identifier: string; - url: string; -} - -const publishedPackages: ReleaseResult[] = []; -const skippedPackages: ReleaseResult[] = []; - -for (const branch of tree) { - startGroup(`Releasing ${branch.map((entry) => `${entry.name}@${entry.version}`).join(", ")}`); - - await Promise.all( - branch.map(async (release) => { - const published = await releasePackage(release, dry, tag); - const identifier = `${release.name}@${release.version}`; - - if (published) { - publishedPackages.push({ identifier, url: npmPackageLink(release.name) }); - } else { - skippedPackages.push({ identifier, url: npmPackageLink(release.name) }); - } - }), - ); - - endGroup(); -} - -const result = summary.addHeading("Release summary"); - -if (dry) { - result.addRaw("\n\n> [!NOTE]\n> This is a dry run.\n\n"); -} - -result.addHeading("Released", 2); - -if (publishedPackages.length === 0) { - result.addRaw("\n_None_\n\n"); -} else { - result.addRaw("\n"); - - for (const { identifier, url } of publishedPackages) { - result.addRaw(`- [${identifier}](${url})\n`); - } - - result.addRaw(`\n`); -} - -result.addHeading("Skipped", 2); - -if (skippedPackages.length === 0) { - result.addRaw("\n_None_\n\n"); -} else { - result.addRaw("\n"); - - for (const { identifier, url } of skippedPackages) { - result.addRaw(`- [${identifier}](${url})\n`); - } - - result.addRaw(`\n`); -} - -await result.write(); diff --git a/utils/actions/src/release-packages/release-package.ts b/utils/actions/src/release-packages/release-package.ts deleted file mode 100644 index dc32e84..0000000 --- a/utils/actions/src/release-packages/release-package.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { info, warning } from "@actions/core"; -import { context, getOctokit } from "@actions/github"; -import { $ } from "bun"; -import process from "node:process"; - -import type { ReleaseEntry } from "./generate-release-tree"; - -let octokit: ReturnType | undefined; - -if (process.env.GITHUB_TOKEN) { - octokit = getOctokit(process.env.GITHUB_TOKEN); -} - -async function checkRegistry(release: ReleaseEntry) { - const res = await fetch(`https://registry.npmjs.org/${release.name}/${release.version}`); - return res.ok; -} - -async function gitTagAndRelease(release: ReleaseEntry, dry: boolean) { - const tagName = `${release.name}@${release.version}`; - - if (dry) { - info(`[DRY] Release would be "${tagName}", skipping release creation.`); - return; - } - - try { - await octokit?.rest.repos.createRelease({ - ...context.repo, - tag_name: tagName, - name: tagName, - body: release.changelog ?? "", - generate_release_notes: release.changelog === undefined, - make_latest: "true", - }); - } catch (error) { - warning(`Failed to create github release: ${error}`); - } -} - -export async function releasePackage( - release: ReleaseEntry, - dry: boolean, - devTag?: string, - doGitRelease = !devTag, -) { - // Sanity check against the registry first - if (await checkRegistry(release)) { - info(`${release.name}@${release.version} already published, skipping.`); - return false; - } - - if (dry) { - info(`[DRY] Releasing ${release.name}@${release.version}`); - } else { - await $`pnpm --filter=${release.name} publish --provenance --no-git-checks ${devTag ? `--tag=${devTag}` : ""}`; - } - - // && !devTag just to be sure - if (doGitRelease && !devTag) await gitTagAndRelease(release, dry); - - if (dry) return true; - - const before = performance.now(); - - // Poll registry to ensure next publishes won't fail - await new Promise((resolve, reject) => { - const interval = setInterval(async () => { - if (await checkRegistry(release)) { - clearInterval(interval); - resolve(); - return; - } - - if (performance.now() > before + 5 * 60 * 1_000) { - clearInterval(interval); - reject(new Error(`Release for ${release.name} failed.`)); - } - }, 15_000); - }); - - return true; -} diff --git a/utils/actions/tsconfig.json b/utils/actions/tsconfig.json deleted file mode 100644 index b8e2058..0000000 --- a/utils/actions/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig.json", - "extends": "../../tsconfig.json", - "compilerOptions": { - "types": ["node"], - "skipLibCheck": true - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist"] -} diff --git a/utils/actions/tsup.config.ts b/utils/actions/tsup.config.ts deleted file mode 100644 index 29b1448..0000000 --- a/utils/actions/tsup.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createTsupConfig } from "../../tsup.config.js"; - -const createConfig = (name: string, entries: string[] = []) => { - return createTsupConfig({ - entry: [`src/${name}/action.yml`, ...entries.map((entry) => `src/${name}/${entry}`)], - outDir: `dist/${name}`, - dts: false, - format: "esm", - minify: "terser", - target: "esnext", - }); -}; - -export default [ - createConfig("create-release-pr", ["index.ts"]), - createConfig("create-release-tag", ["index.ts"]), - createConfig("release-packages", ["index.ts"]), -];