diff --git a/.github/workflows/publish-unstable.yml b/.github/workflows/publish-unstable.yml new file mode 100644 index 000000000..2afe4a8d4 --- /dev/null +++ b/.github/workflows/publish-unstable.yml @@ -0,0 +1,35 @@ +# For every push to the master branch, this publishes an NPM package to the +# "unstable" NPM tag. + +name: Publish Unstable + +on: + push: + branches: + - main + +concurrency: + group: ci-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + publish: + name: "NPM Publish" + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/setup + - name: Install Node + uses: actions/setup-node@v3 + with: + # This creates an .npmrc that reads the NODE_AUTH_TOKEN environment variable + registry-url: 'https://registry.npmjs.org' + + - name: set versions + run: node ./test-packages/unstable-release/version.js + + - name: npm publish + run: node ./test-packages/unstable-release/publish.js + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/test-packages/unstable-release/.eslintrc.cjs b/test-packages/unstable-release/.eslintrc.cjs new file mode 100644 index 000000000..bc1f19a2b --- /dev/null +++ b/test-packages/unstable-release/.eslintrc.cjs @@ -0,0 +1,32 @@ +'use strict'; + +module.exports = { + root: true, + parser: 'babel-eslint', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + legacyDecorators: true, + }, + }, + extends: ['eslint:recommended', 'plugin:prettier/recommended'], + env: { + browser: true, + }, + overrides: [ + // node files + { + files: ['./.eslintrc.cjs'], + parserOptions: { + sourceType: 'script', + }, + env: { + browser: false, + node: true, + }, + plugins: ['node'], + extends: ['plugin:node/recommended'], + }, + ], +}; diff --git a/test-packages/unstable-release/README.md b/test-packages/unstable-release/README.md new file mode 100644 index 000000000..2cbd4672b --- /dev/null +++ b/test-packages/unstable-release/README.md @@ -0,0 +1,9 @@ +# @embroider/unstable-release + +Tools for supporting unstable releases off `main`. + +_The changes this package makes to the monorepo should not be committed_. + +```bash +node ./test-packages/unstable-release/version.js +``` diff --git a/test-packages/unstable-release/package.json b/test-packages/unstable-release/package.json new file mode 100644 index 000000000..9628fb683 --- /dev/null +++ b/test-packages/unstable-release/package.json @@ -0,0 +1,23 @@ +{ + "name": "@embroider/unstable-release", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "lint:js": "eslint . --cache --config ./.eslintrc.cjs" + }, + "dependencies": { + "execa": "^7.0.0", + "fs-extra": "^9.1.0", + "globby": "^11.0.3" + }, + "volta": { + "extends": "../../package.json" + }, + "devDependencies": { + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-node": "^11.1.0", + "prettier": "^2.5.1" + } +} diff --git a/test-packages/unstable-release/publish.js b/test-packages/unstable-release/publish.js new file mode 100644 index 000000000..84e11ee55 --- /dev/null +++ b/test-packages/unstable-release/publish.js @@ -0,0 +1,14 @@ +import { execaCommand } from 'execa'; +import { listPublicWorkspaces } from './workspaces.js'; +import { dirname } from 'path'; + +async function publish() { + let publicWorkspaces = await listPublicWorkspaces(); + + for (let workspace of publicWorkspaces) { + console.info(`Publishing ${workspace}`); + await execaCommand('npm publish --tag=unstable --verbose', { cwd: dirname(workspace) }); + } +} + +publish(); diff --git a/test-packages/unstable-release/version.js b/test-packages/unstable-release/version.js new file mode 100644 index 000000000..8634dc38e --- /dev/null +++ b/test-packages/unstable-release/version.js @@ -0,0 +1,61 @@ +import fse from 'fs-extra'; +import { listPublicWorkspaces, currentSHA } from './workspaces.js'; + +/** + * This is an I/O heavy way to do this, but hopefully it reads easy + * + * these functions change the CWD as they go, returnning to he previous + * CWD via finally blocks upon finish. + */ +async function updateVersions() { + let sha = await currentSHA(); + + let publicWorkspaces = await listPublicWorkspaces(); + + // Pick new versions for each package + for (let workspace of publicWorkspaces) { + console.info(`Setting version of ${workspace}`); + await setVersion(sha, workspace); + } + + // Update each dependency to use the new versions + for (let workspace of publicWorkspaces) { + console.info(`Updating dependencies of ${workspace}`); + await updateDependencies(workspace); + } +} + +updateVersions(); + +//////////////////////////////////////////// + +const NEW_VERSIONS = {}; + +async function setVersion(sha, filePath) { + let json = await fse.readJSON(filePath); + json.version = `${json.version}-unstable.${sha}`; + + NEW_VERSIONS[json.name] = json.version; + + await fse.writeJSON(filePath, json, { spaces: 2 }); +} + +async function updateDependencies(filePath) { + let json = await fse.readJSON(filePath); + + for (let [dep, version] of Object.entries(NEW_VERSIONS)) { + if ((json.dependencies || {})[dep]) { + json.dependencies[dep] = version; + } + + if ((json.devDependencies || {})[dep]) { + json.devDependencies[dep] = version; + } + + if ((json.peerDependencies || {})[dep]) { + json.peerDependencies[dep] = version; + } + } + + await fse.writeJSON(filePath, json, { spaces: 2 }); +} diff --git a/test-packages/unstable-release/workspaces.js b/test-packages/unstable-release/workspaces.js new file mode 100644 index 000000000..d52294c8a --- /dev/null +++ b/test-packages/unstable-release/workspaces.js @@ -0,0 +1,30 @@ +import globby from 'globby'; +import { execaCommand } from 'execa'; +import fse from 'fs-extra'; + +/** + * All publishable packages are in packages/* + * + * We could read package.json#workspaces, but then we'd have more to filter out. + */ +export async function listPublicWorkspaces() { + let filePaths = await globby(['packages/*/package.json']); + + let result = []; + + for (let filePath of filePaths) { + let packageJson = await fse.readJSON(filePath); + + if (packageJson.private) continue; + + result.push(filePath); + } + + return result; +} + +export async function currentSHA() { + let { stdout } = await execaCommand(`git rev-parse --short HEAD`); + + return stdout.trim(); +} diff --git a/yarn.lock b/yarn.lock index 02d324244..46cc64273 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5409,26 +5409,7 @@ browserslist-generator@^1.0.66: semver "^7.3.7" ua-parser-js "^1.0.2" -browserslist@4.20.2: - version "4.20.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" - integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== - dependencies: - caniuse-lite "^1.0.30001317" - electron-to-chromium "^1.4.84" - escalade "^3.1.1" - node-releases "^2.0.2" - picocolors "^1.0.0" - -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.20.4, browserslist@^4.21.3, browserslist@^4.21.4: +browserslist@4.20.2, browserslist@^3.2.6, browserslist@^4.0.0, browserslist@^4.14.0, browserslist@^4.14.5, browserslist@^4.20.4, browserslist@^4.21.3, browserslist@^4.21.4: version "4.21.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== @@ -5587,11 +5568,6 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001328: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz#ab7371faeb4adff4b74dad1718a6fd122e45d9cb" integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A== -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001317: - version "1.0.30001458" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c" - integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w== - caniuse-lite@^1.0.30001449: version "1.0.30001457" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" @@ -6693,11 +6669,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.84: - version "1.4.315" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.315.tgz#b60a6676b3a1db332cfc8919118344aa06b9ac99" - integrity sha512-ndBQYz3Eyy3rASjjQ9poMJGoAlsZ/aZnq6GBsGL4w/4sWIAwiUHVSsMuADbxa8WJw7pZ0oxLpGbtoDt4vRTdCg== - electron-to-chromium@^1.4.284: version "1.4.302" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.302.tgz#5770646ffe7051677b489226144aad9386d420f2" @@ -9007,6 +8978,21 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.0.0.tgz#2a44e20e73797f6c2df23889927972386157d7e4" + integrity sha512-tQbH0pH/8LHTnwTrsKWideqi6rFB/QNUawEwrn+WHyz7PX1Tuz2u7wfTvbaNBdP5JD5LVWxNo8/A8CHNZ3bV6g== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -9873,7 +9859,7 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -get-stream@^6.0.0: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -10106,7 +10092,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.0.0, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -10438,6 +10424,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.0.tgz#2095c3cd5afae40049403d4b811235b03879db50" + integrity sha512-zyzVyMjpGBX2+6cDVZeFPCdtOtdsxOeseRhB9tkQ6xXmGUNrcnBzdEKPy3VPNYz+4gy1oukVOXcrJCunSyc6QQ== + iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -10956,6 +10947,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -12542,6 +12538,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -12778,7 +12779,7 @@ node-notifier@^10.0.0: uuid "^8.3.2" which "^2.0.2" -node-releases@^2.0.2, node-releases@^2.0.8: +node-releases@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== @@ -12896,6 +12897,13 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + npmlog@^6.0.0: version "6.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" @@ -13043,6 +13051,13 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + optionator@^0.8.1, optionator@^0.8.2: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -13365,6 +13380,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -13755,7 +13775,7 @@ qunit-dom@^2.0.0: ember-cli-babel "^7.23.0" ember-cli-version-checker "^5.1.1" -qunit@^2.16.0, qunit@^2.19.1: +qunit@^2.14.1, qunit@^2.16.0, qunit@^2.19.1: version "2.19.4" resolved "https://registry.yarnpkg.com/qunit/-/qunit-2.19.4.tgz#2d689bb1165edd4b812e3ed2ee06ff907e9f2ece" integrity sha512-aqUzzUeCqlleWYKlpgfdHHw9C6KxkB9H3wNfiBg5yHqQMzy0xw/pbCRHYFkjl8MsP/t8qkTQE+JTYL71azgiew== @@ -15166,6 +15186,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"