mirror of
https://github.com/AventurasTeam/Aventuras.git
synced 2026-10-25 08:00:41 +00:00
## Summary Node 24 migration, plus a CI/CD overhaul that puts desktop and Android builds behind one shared, cached, and now release-safe set of workflows — used by pull-request validation, `master`, and both release tracks alike. ## What changed **Node & Actions** - Node 24, tracked via `.nvmrc` (`package.json`'s `devEngines` enforces it; the README points at `.nvmrc` instead of a hardcoded version) - GitHub Actions bumped off versions that were 1-3 majors behind, several still on the deprecated Node 20 runtime **Shared, safer release workflows** - Desktop and Android build jobs now live in reusable workflows (`build-desktop.yml`, `build-android.yml`), called by `master`/PR validation and both `release.yml` and `pre-release.yml` with a `publish`/`prerelease` switch — previously each release workflow duplicated its own copy of the whole build matrix - A `create-release` job creates the release once per run, so the build matrix's parallel legs stop racing to create duplicate draft releases - A release-safety guard now refuses to run when the tag's release is already published, or when a pushed tag doesn't match `tauri.conf.json`'s version — protects a shipped release's assets and `prerelease` flag from a stray `workflow_dispatch` or job re-run - Pre-releases are now created as a draft and only published once every platform build succeeds, matching how stable releases already worked - Runners are pinned (`macos-15`, `windows-2025`) instead of tracking `-latest`, and the Linux desktop build runs inside an `ubuntu:22.04` container, independent of the `ubuntu-latest` host's own lifecycle **CI now builds and caches on `master`** - Every platform now builds on `master` (on push, a weekly schedule, and manual dispatch) without publishing, so tag-triggered release builds — which can only restore caches from the tag itself or the default branch — no longer start cold, and every push leaves a downloadable per-platform build - Rust, Gradle and npm all get real caches now; the npm cache key ignores the version-bump commit every release makes, so releases hit the cache too - `lint-and-typecheck.yml` now also runs `npm test`, which CI never did before, and installs dependencies through the same cached action as the rest of CI **Build changes** - Android builds an APK only (the AAB was built and discarded every run) and drops the 32-bit `x86` target; it uses the runner's preinstalled NDK instead of downloading one, and drops the Android SDK's no-longer-published `tools` package - A release-mode Tauri config drops the `devtools` feature from release builds - A CI-only build gets a SHA-suffixed version instead of silently reusing the last release's version **Fixes found along the way** - A release-name typo (`Aventura` → `Aventuras`) that `tauri-action` would otherwise have kept reverting - The CI version suffix can no longer produce an invalid semver identifier ## Docs `docs/development/release.md` substantially rewritten to cover the shared-workflow architecture, the release-safety guard, the caching setup, and the build-version scheme. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added automated desktop and Android builds for Linux, Windows, macOS, and Android. - Added signed artifacts, draft releases, prereleases, and platform-specific downloads. - Added scheduled and manually triggered builds that create downloadable artifacts without publishing a release. - Added macOS Apple Silicon and Linux RPM packages, plus updated Android and desktop asset naming. - Added safeguards to prevent duplicate uploads to published releases. - **Documentation** - Updated build prerequisites and documented automated linting, type-checking, tests, and builds. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
82 lines
2.9 KiB
JavaScript
82 lines
2.9 KiB
JavaScript
/**
|
|
* Version arithmetic for `scripts/release.js`. Split out so it can be tested.
|
|
*
|
|
* The rules match `semver.inc`. `semver` is not imported: it is only a transitive
|
|
* dependency here, and a release script that breaks when an unrelated package drops it is
|
|
* worse than forty lines of arithmetic.
|
|
*/
|
|
|
|
/**
|
|
* Versions this project can release. Stricter than semver, because a tag is only worth
|
|
* making if a workflow builds it: `release.yml` triggers on `v[0-9]+.[0-9]+.[0-9]+` and
|
|
* `pre-release.yml` on `v*-pre*`, so a legal `1.2.3-beta.1` would tag, push and build nothing.
|
|
*/
|
|
const VERSION_PATTERN = /^(\d+)\.(\d+)\.(\d+)(?:-pre\.(\d+))?$/
|
|
|
|
export function isValidVersion(version) {
|
|
return typeof version === 'string' && VERSION_PATTERN.test(version)
|
|
}
|
|
|
|
export function parseVersion(version) {
|
|
const match = VERSION_PATTERN.exec(version)
|
|
if (!match) return null
|
|
return {
|
|
major: Number(match[1]),
|
|
minor: Number(match[2]),
|
|
patch: Number(match[3]),
|
|
pre: match[4] === undefined ? null : Number(match[4]),
|
|
}
|
|
}
|
|
|
|
/** Negative if `a` precedes `b`, positive if it follows, zero if equal. */
|
|
export function compareVersions(a, b) {
|
|
const x = parseVersion(a)
|
|
const y = parseVersion(b)
|
|
if (!x || !y) throw new Error(`Cannot compare unparseable versions: "${a}", "${b}"`)
|
|
|
|
for (const part of ['major', 'minor', 'patch']) {
|
|
if (x[part] !== y[part]) return x[part] - y[part]
|
|
}
|
|
// A pre-release precedes the release it leads to: 0.7.6-pre.1 < 0.7.6.
|
|
if (x.pre === null && y.pre === null) return 0
|
|
if (x.pre === null) return 1
|
|
if (y.pre === null) return -1
|
|
return x.pre - y.pre
|
|
}
|
|
|
|
/**
|
|
* Apply `type` to `current`: a bump type, or a literal version string.
|
|
*
|
|
* A pre-release already sitting at the level being bumped is promoted rather than
|
|
* incremented — `0.7.6-pre.1` + `patch` is `0.7.6` — because only the suffix stands
|
|
* between it and release.
|
|
*/
|
|
export function bumpVersion(current, type) {
|
|
const v = parseVersion(current)
|
|
if (!v) throw new Error(`Current version is not a version this project can release: ${current}`)
|
|
if (!type) return undefined
|
|
|
|
const isPre = v.pre !== null
|
|
|
|
switch (type) {
|
|
case 'major':
|
|
// Promote only on the major boundary (X.0.0-pre.N).
|
|
return isPre && v.minor === 0 && v.patch === 0 ? `${v.major}.0.0` : `${v.major + 1}.0.0`
|
|
|
|
case 'minor':
|
|
return isPre && v.patch === 0 ? `${v.major}.${v.minor}.0` : `${v.major}.${v.minor + 1}.0`
|
|
|
|
case 'patch':
|
|
return isPre ? `${v.major}.${v.minor}.${v.patch}` : `${v.major}.${v.minor}.${v.patch + 1}`
|
|
|
|
case 'prerelease':
|
|
// From a stable version the patch moves first: `0.7.6-pre.1` sorts *before* the
|
|
// `0.7.6` already shipped, so an updater would offer users a downgrade.
|
|
return isPre
|
|
? `${v.major}.${v.minor}.${v.patch}-pre.${v.pre + 1}`
|
|
: `${v.major}.${v.minor}.${v.patch + 1}-pre.1`
|
|
|
|
default:
|
|
return type
|
|
}
|
|
}
|