Setup v4 releases (#15961)

Now that Tailwind CSS v4 is released, we can setup a proper release
workflow again. This setup mimics the workflow of how we did it in v3,
but adjusted to make it work on the v4 codebase.

Whenever a PR is merged into the `next` branch, we will publish an
insiders release to npm using the following version number:
`0.0.0-insiders.<commit-hash>`. Note: insiders releases will not have a
GitHub release associated with them, therefore the `standalone-cli`
won't be available as an insiders release.

For the normal release procedure, the following steps are required:

1. Manually version the packages (e.g.: `pnpm run version-packages`)
2. Create a git tag for the version you want to release
3. Push the updated package.json files and the git tag to the repository

Next, a GitHub action will kick in once a `tag` is being pushed.

The GitHub action will run a build, and create a draft release on GitHub
that will contain:

1. The CHANGELOG.md contents for the last version
2. The `standalone-cli` artifacts attached to the drafted release

Once you are happy with the draft, you can publish the draft on GitHub.

This in turn will trigger another GitHub action that will publish the
packages to npm.

Whenever an insiders release or a normal release completes, we will also
trigger Tailwind Play, to update its dependencies to the latest version
of Tailwind CSS.

---

Note: some of the GitHub Action workflows still refer to the `next`
branch instead of the `main` branch. If we later today want to get a new
release out, we can merge `next` into `main` and update the workflows
accordingly.


---

This is hard to test, but I started from the existing release.yml file
and adjusted things accordingly. The biggest change is related to the
insiders version. If you look at this temporary
[commit](572dddfc33),
you can see that the publishing (dry-run) seems to work as expected:
<img width="1508" alt="image"
src="https://github.com/user-attachments/assets/c075e788-dcbc-4200-aa32-2b9a3c54d629"
/>
This commit is contained in:
Robin Malfait 2025-01-28 12:51:34 +01:00 • committed by GitHub
parent 2c1dea4c1a
commit 515a9bdc5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 560 additions and 53 deletions

View file

@ -0,0 +1,20 @@
// Given a version, figure out what the release channel is so that we can publish to the correct
// channel on npm.
//
// E.g.:
//
// 1.2.3 -> latest (default)
// 0.0.0-insiders.ffaa88 -> insiders
// 4.1.0-alpha.4 -> alpha
let version =
process.argv[2] ||
process.env.npm_package_version ||
require('../packages/tailwindcss/package.json').version
let match = /\d+\.\d+\.\d+-(.*)\.\d+/g.exec(version)
if (match) {
console.log(match[1])
} else {
console.log('latest')
}

View file

@ -8,6 +8,7 @@ import prettier from 'prettier'
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
const root = path.resolve(__dirname, '..')
const version = process.argv[2] || null
// The known workspace is: @tailwindcss/oxide
// All the workspaces in `crates/node/npm/*` should always be in sync with
@ -52,6 +53,34 @@ exec('pnpm --silent --filter=!./playgrounds/* -r exec pwd', async (err, stdout)
process.exit(1)
}
if (version !== null) {
for (let pkgPath of stdout
.trim()
.split('\n')
.map((x) => path.resolve(x, 'package.json'))) {
let pkg = await fs.readFile(pkgPath, 'utf8').then(JSON.parse)
let name = pkg.name
if (version !== '') {
// Ensure the version is set after the name and before everything else
delete pkg.name
delete pkg.version
// This allows us to keep the order of the keys in the package.json
pkg = { name, version, ...pkg }
}
await fs.writeFile(
pkgPath,
await prettier
.format(JSON.stringify(pkg, null, 2), { filepath: pkgPath })
.then((x) => `${x.trim()}\n`),
)
}
console.log('Done.')
return
}
let paths = stdout
.trim()
.split('\n')