mirror of
https://github.com/immich-app/immich.git
synced 2026-05-28 02:22:34 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 20c8bbd35f |
@@ -17,11 +17,6 @@ on:
|
||||
description: 'Bump mobile build number'
|
||||
required: false
|
||||
type: boolean
|
||||
rc:
|
||||
description: 'Release candidate'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
skipTranslations:
|
||||
description: 'Skip translations'
|
||||
required: false
|
||||
@@ -79,8 +74,7 @@ jobs:
|
||||
env:
|
||||
SERVER_BUMP: ${{ inputs.serverBump }}
|
||||
MOBILE_BUMP: ${{ inputs.mobileBump }}
|
||||
RC: ${{ inputs.rc }}
|
||||
run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}" -r "${RC}"
|
||||
run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
|
||||
|
||||
- id: output
|
||||
run: echo "version=$IMMICH_VERSION" >> $GITHUB_OUTPUT
|
||||
@@ -114,7 +108,7 @@ jobs:
|
||||
|
||||
with:
|
||||
ref: ${{ needs.bump_version.outputs.ref }}
|
||||
environment: ${{ inputs.rc && 'rc' || 'production' }}
|
||||
environment: production
|
||||
|
||||
prepare_release:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -146,7 +140,6 @@ jobs:
|
||||
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
|
||||
with:
|
||||
draft: true
|
||||
prerelease: ${{ inputs.rc }}
|
||||
tag_name: ${{ needs.bump_version.outputs.version }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
generate_release_notes: true
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# Release Candidate (RC)
|
||||
|
||||
The Release Candidate channel is an opt-in track for the next Immich version, published roughly one week ahead of the official release. RC builds are labeled `vX.Y.Z-rc.N` and may contain bugs — testers help us catch them before everyone else gets the update.
|
||||
|
||||
## Why participate
|
||||
|
||||
Joining the RC channel lets you preview the next version, surface regressions that are easier to fix before release, and shape the build that lands for everyone. Feedback you give here makes it into the final cut.
|
||||
|
||||
## iOS — Public TestFlight
|
||||
|
||||
1. Install Apple's [TestFlight](https://apps.apple.com/app/testflight/id899247664) app.
|
||||
2. Open the public RC TestFlight link: `<TESTFLIGHT_LINK_PLACEHOLDER>`.
|
||||
3. Tap **Accept**, then **Install**.
|
||||
|
||||
:::info Separate app on your device
|
||||
The RC build is a distinct app — "Immich RC" — that installs alongside your production Immich. Your data is not shared between the two. Sign in to your server in the RC app the same way you would on a fresh install.
|
||||
:::
|
||||
|
||||
## Android — Open Testing
|
||||
|
||||
1. Open the Play Store opt-in link: `<PLAY_STORE_OPT_IN_PLACEHOLDER>`.
|
||||
2. Tap **Become a tester**.
|
||||
|
||||
:::warning RC replaces your production install
|
||||
Android RC builds use the same package name as production Immich, so the Play Store delivers them as updates on top of your existing install. This is a one-way change until you opt out and reinstall — there is no separate "Immich RC" app on Android.
|
||||
:::
|
||||
|
||||
## Server, web, CLI
|
||||
|
||||
RC server images are not part of this initial rollout. For now, if you want to test an RC backend alongside an RC mobile build, build the server from the `vX.Y.Z-rc.N` git tag yourself. We may publish `:rc` Docker tags later.
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Open a GitHub issue at the [Immich issue tracker](https://github.com/immich-app/immich/issues). Mention that you are on an RC build and include the version string (`vX.Y.Z-rc.N`) so we can correlate reports across testers.
|
||||
|
||||
:::note
|
||||
Test against a non-critical library or a staging instance — not your only copy of family photos. RCs are pre-release software and may have bugs that affect data.
|
||||
:::
|
||||
|
||||
## Leaving the RC channel
|
||||
|
||||
- **iOS**: Open TestFlight → Immich RC → **Stop Testing**. The RC app stays installed until you delete it; deleting it does not affect your production Immich install.
|
||||
- **Android**: Open the Play Store → Immich → scroll to **You're a tester** → leave the program. Then uninstall and reinstall Immich to drop back to the production track.
|
||||
|
||||
## Cadence
|
||||
|
||||
We typically publish one to three RCs in the ~1 week before each minor release. Patch releases usually skip the RC stage and ship straight to production.
|
||||
@@ -5,3 +5,5 @@ The mobile app can be downloaded from the following places:
|
||||
- [Apple App Store](https://apps.apple.com/us/app/immich/id1613945652)
|
||||
- [F-Droid](https://f-droid.org/packages/app.alextran.immich)
|
||||
- [GitHub Releases (apk)](https://github.com/immich-app/immich/releases)
|
||||
|
||||
Want to help test the next release before it ships? Join the [Release Candidate channel](/features/release-candidate).
|
||||
|
||||
@@ -1,42 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# Pump one or both of the server/mobile versions in appropriate files.
|
||||
# Pump one or both of the server/mobile versions in appropriate files
|
||||
#
|
||||
# Usage:
|
||||
# ./misc/release/pump-version.sh [-s <major|minor|patch>] [-m <true|false>] [-r <true|false>]
|
||||
# usage: './scripts/pump-version.sh -s <major|minor|patch> <-m> <true|false>
|
||||
#
|
||||
# Flags:
|
||||
# -s <major|minor|patch> Server version bump scope. Omit to leave the server
|
||||
# version unchanged, except when finalizing an RC (see -r).
|
||||
# (default: false)
|
||||
# -m <true|false> Whether to increment the mobile build number.
|
||||
# (default: false)
|
||||
# -r <true|false> Release candidate mode. When true, starts a new RC
|
||||
# (combined with -s) or iterates an existing one. When
|
||||
# false while the current version is already an RC,
|
||||
# finalizes it (e.g. 3.1.0-rc.2 => 3.1.0). A server bump
|
||||
# is rejected while on an RC; finalize first.
|
||||
# (default: false)
|
||||
#
|
||||
# Examples:
|
||||
# ./misc/release/pump-version.sh -s major # 1.0.0+50 => 2.0.0+50
|
||||
# ./misc/release/pump-version.sh -s minor -m true # 1.0.0+50 => 1.1.0+51
|
||||
# ./misc/release/pump-version.sh -m true # 1.0.0+50 => 1.0.0+51
|
||||
# ./misc/release/pump-version.sh -s minor -m true -r true # 3.0.0 => 3.1.0-rc.0 (start RC)
|
||||
# ./misc/release/pump-version.sh -m true -r true # 3.1.0-rc.0 => 3.1.0-rc.1 (iterate RC)
|
||||
# ./misc/release/pump-version.sh -m true # 3.1.0-rc.1 => 3.1.0 (finalize RC)
|
||||
# examples:
|
||||
# ./scripts/pump-version.sh -s major # 1.0.0+50 => 2.0.0+50
|
||||
# ./scripts/pump-version.sh -s minor -m true # 1.0.0+50 => 1.1.0+51
|
||||
# ./scripts/pump-version.sh -m true # 1.0.0+50 => 1.0.0+51
|
||||
#
|
||||
|
||||
SERVER_PUMP="false"
|
||||
MOBILE_PUMP="false"
|
||||
RC="false"
|
||||
|
||||
while getopts 's:m:r:' flag; do
|
||||
while getopts 's:m:' flag; do
|
||||
case "${flag}" in
|
||||
s) SERVER_PUMP=${OPTARG} ;;
|
||||
m) MOBILE_PUMP=${OPTARG} ;;
|
||||
r) RC=${OPTARG} ;;
|
||||
*)
|
||||
echo "Invalid args"
|
||||
exit 1
|
||||
@@ -44,60 +25,28 @@ while getopts 's:m:r:' flag; do
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$RC" != "true" && "$RC" != "false" ]]; then
|
||||
echo "Expected <true|false> for the -r argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT_SERVER=$(jq -r '.version' server/package.json)
|
||||
MAJOR=$(echo "$CURRENT_SERVER" | cut -d '.' -f1)
|
||||
MINOR=$(echo "$CURRENT_SERVER" | cut -d '.' -f2)
|
||||
PATCH=$(echo "$CURRENT_SERVER" | cut -d '.' -f3)
|
||||
|
||||
if [[ "$CURRENT_SERVER" == *-rc.* ]]; then
|
||||
CURRENT_BASE="${CURRENT_SERVER%-rc.*}"
|
||||
CURRENT_RC_NUM="${CURRENT_SERVER##*-rc.}"
|
||||
if [[ $SERVER_PUMP == "major" ]]; then
|
||||
MAJOR=$((MAJOR + 1))
|
||||
MINOR=0
|
||||
PATCH=0
|
||||
elif [[ $SERVER_PUMP == "minor" ]]; then
|
||||
MINOR=$((MINOR + 1))
|
||||
PATCH=0
|
||||
elif [[ $SERVER_PUMP == "patch" ]]; then
|
||||
PATCH=$((PATCH + 1))
|
||||
elif [[ $SERVER_PUMP == "false" ]]; then
|
||||
echo 'Skipping Server Pump'
|
||||
else
|
||||
CURRENT_BASE="$CURRENT_SERVER"
|
||||
CURRENT_RC_NUM=""
|
||||
fi
|
||||
|
||||
# Validate RC/server-bump combinations against current version state
|
||||
if [[ -n "$CURRENT_RC_NUM" ]]; then
|
||||
# Currently on an RC: -r true iterates, -r false finalizes. Either way, a server bump is invalid.
|
||||
if [[ "$SERVER_PUMP" != "false" ]]; then
|
||||
echo "Cannot bump server while on an RC ($CURRENT_SERVER); finalize first by re-running with -r false and no -s."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Not currently on an RC
|
||||
if [[ "$RC" == "true" && "$SERVER_PUMP" == "false" ]]; then
|
||||
echo "Starting an RC requires a server bump."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$SERVER_PUMP" != "major" && "$SERVER_PUMP" != "minor" && "$SERVER_PUMP" != "patch" && "$SERVER_PUMP" != "false" ]]; then
|
||||
echo 'Expected <major|minor|patch|false> for the server argument'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NEXT_SERVER="$CURRENT_SERVER"
|
||||
if [[ "$SERVER_PUMP" == "false" && "$RC" == "false" && -z "$CURRENT_RC_NUM" ]]; then
|
||||
echo 'Skipping Server Pump'
|
||||
else
|
||||
npm version "$CURRENT_SERVER" --allow-same-version --no-git-tag-version || exit 1
|
||||
|
||||
if [[ "$RC" == "true" && -n "$CURRENT_RC_NUM" ]]; then
|
||||
npm version prerelease --no-git-tag-version || exit 1
|
||||
elif [[ "$RC" == "true" ]]; then
|
||||
npm version "pre$SERVER_PUMP" --preid=rc --no-git-tag-version || exit 1
|
||||
elif [[ -n "$CURRENT_RC_NUM" ]]; then
|
||||
# rc=false while on an RC → finalize
|
||||
npm version "$CURRENT_BASE" --no-git-tag-version || exit 1
|
||||
else
|
||||
npm version "$SERVER_PUMP" --no-git-tag-version || exit 1
|
||||
fi
|
||||
|
||||
NEXT_SERVER=$(jq -r '.version' package.json)
|
||||
fi
|
||||
NEXT_SERVER=$MAJOR.$MINOR.$PATCH
|
||||
|
||||
CURRENT_MOBILE=$(grep "^version: .*+[0-9]\+$" mobile/pubspec.yaml | cut -d "+" -f2)
|
||||
NEXT_MOBILE=$CURRENT_MOBILE
|
||||
@@ -113,6 +62,7 @@ fi
|
||||
if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
|
||||
echo "Pumping Server: $CURRENT_SERVER => $NEXT_SERVER"
|
||||
|
||||
pnpm version "$NEXT_SERVER" --no-git-tag-version
|
||||
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix server
|
||||
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix packages/cli
|
||||
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix web
|
||||
@@ -122,12 +72,9 @@ if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
|
||||
# copy version to open-api spec
|
||||
mise run //:open-api
|
||||
|
||||
NEXT_PY="${NEXT_SERVER//-rc./rc}"
|
||||
uv version --directory machine-learning "$NEXT_PY"
|
||||
uv version --directory machine-learning "$NEXT_SERVER"
|
||||
|
||||
if [[ "$NEXT_SERVER" != *-rc.* ]]; then
|
||||
./misc/release/archive-version.js "$NEXT_SERVER"
|
||||
fi
|
||||
./misc/release/archive-version.js "$NEXT_SERVER"
|
||||
fi
|
||||
|
||||
if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then
|
||||
@@ -137,9 +84,7 @@ fi
|
||||
sed -i "s/\"android\.injected\.version\.name\" => \"$CURRENT_SERVER\",/\"android\.injected\.version\.name\" => \"$NEXT_SERVER\",/" mobile/android/fastlane/Fastfile
|
||||
sed -i "s/\"android\.injected\.version\.code\" => $CURRENT_MOBILE,/\"android\.injected\.version\.code\" => $NEXT_MOBILE,/" mobile/android/fastlane/Fastfile
|
||||
sed -i "s/^version: $CURRENT_SERVER+$CURRENT_MOBILE$/version: $NEXT_SERVER+$NEXT_MOBILE/" mobile/pubspec.yaml
|
||||
# iOS marketing version cannot contain a pre-release suffix; the plist always holds the base version.
|
||||
IOS_NEXT="${NEXT_SERVER%-rc.*}"
|
||||
perl -i -p0e "s/(<key>CFBundleShortVersionString<\/key>\s*<string>)$CURRENT_BASE(<\/string>)/\${1}$IOS_NEXT\${2}/s" mobile/ios/Runner/Info.plist
|
||||
perl -i -p0e "s/(<key>CFBundleShortVersionString<\/key>\s*<string>)$CURRENT_SERVER(<\/string>)/\${1}$NEXT_SERVER\${2}/s" mobile/ios/Runner/Info.plist
|
||||
|
||||
|
||||
echo "IMMICH_VERSION=v$NEXT_SERVER" >>"$GITHUB_ENV"
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { dirname, join, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = resolve(scriptDir, '../..');
|
||||
const scriptUnderTest = join(repoRoot, 'misc/release/pump-version.sh');
|
||||
|
||||
const read = (path) => readFileSync(path, 'utf8');
|
||||
const packageVersion = (dir) => JSON.parse(read(join(dir, 'package.json'))).version;
|
||||
const shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
||||
|
||||
const writeExecutable = (path, contents) => {
|
||||
writeFileSync(path, contents, { mode: 0o755 });
|
||||
};
|
||||
|
||||
const writePackageJson = (dir, name, version) => {
|
||||
writeFileSync(
|
||||
join(dir, 'package.json'),
|
||||
`${JSON.stringify({ name, version, private: true }, null, 2)}\n`,
|
||||
);
|
||||
};
|
||||
|
||||
const makeFixture = (t, { rootVersion = '2.7.5', serverVersion = '3.0.0', mobileBuild = 3047 } = {}) => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), 'pump-version-'));
|
||||
t.after(() => rmSync(workdir, { recursive: true, force: true }));
|
||||
|
||||
const currentBase = serverVersion.replace(/-rc\..+$/, '');
|
||||
|
||||
for (const path of [
|
||||
'bin',
|
||||
'server',
|
||||
'packages/cli',
|
||||
'web',
|
||||
'e2e',
|
||||
'packages/sdk',
|
||||
'misc/release',
|
||||
'mobile/android/fastlane',
|
||||
'mobile/ios/Runner',
|
||||
'machine-learning',
|
||||
]) {
|
||||
mkdirSync(join(workdir, path), { recursive: true });
|
||||
}
|
||||
|
||||
writeCommandStubs(workdir);
|
||||
|
||||
writePackageJson(workdir, 'immich-monorepo', rootVersion);
|
||||
writePackageJson(join(workdir, 'server'), 'immich', serverVersion);
|
||||
writePackageJson(join(workdir, 'packages/cli'), '@immich/cli', serverVersion);
|
||||
writePackageJson(join(workdir, 'web'), 'immich-web', serverVersion);
|
||||
writePackageJson(join(workdir, 'e2e'), 'immich-e2e', serverVersion);
|
||||
writePackageJson(join(workdir, 'packages/sdk'), '@immich/sdk', serverVersion);
|
||||
|
||||
writeExecutable(
|
||||
join(workdir, 'misc/release/archive-version.js'),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
echo "$*" >>"$PWD/archive-version.calls"
|
||||
`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
join(workdir, 'mobile/pubspec.yaml'),
|
||||
`name: immich_mobile
|
||||
version: ${serverVersion}+${mobileBuild}
|
||||
`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
join(workdir, 'mobile/android/fastlane/Fastfile'),
|
||||
`lane :gha_release_prod do
|
||||
gradle(
|
||||
properties: {
|
||||
"android.injected.version.code" => ${mobileBuild},
|
||||
"android.injected.version.name" => "${serverVersion}",
|
||||
}
|
||||
)
|
||||
end
|
||||
`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
join(workdir, 'mobile/ios/Runner/Info.plist'),
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${currentBase}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
`,
|
||||
);
|
||||
|
||||
return {
|
||||
path: workdir,
|
||||
file: (path) => join(workdir, path),
|
||||
readFile: (path) => read(join(workdir, path)),
|
||||
hasFile: (path) => {
|
||||
try {
|
||||
return read(join(workdir, path)).length > 0;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
run: (...args) =>
|
||||
spawnSync('bash', [scriptUnderTest, ...args], {
|
||||
cwd: workdir,
|
||||
env: {
|
||||
...process.env,
|
||||
GITHUB_ENV: join(workdir, 'github_env'),
|
||||
PATH: `${join(workdir, 'bin')}:${process.env.PATH}`,
|
||||
},
|
||||
encoding: 'utf8',
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
const writeCommandStubs = (workdir) => {
|
||||
const realNpm = spawnSync('which', ['npm'], { encoding: 'utf8' }).stdout.trim();
|
||||
|
||||
writeExecutable(
|
||||
join(workdir, 'bin/npm'),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
real_npm=${shellQuote(realNpm)}
|
||||
echo "$*" >>"$PWD/npm.calls"
|
||||
"$real_npm" "$@"
|
||||
`,
|
||||
);
|
||||
|
||||
writeExecutable(
|
||||
join(workdir, 'bin/pnpm'),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "\${1:-}" != "version" ]]; then
|
||||
echo "Unexpected pnpm command: $*" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
version="\${1:-}"
|
||||
shift
|
||||
prefix="."
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--prefix)
|
||||
prefix="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-git-tag-version)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unexpected pnpm argument: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
npm --prefix "$prefix" version "$version" --no-git-tag-version --allow-same-version >/dev/null
|
||||
`,
|
||||
);
|
||||
|
||||
writeExecutable(
|
||||
join(workdir, 'bin/mise'),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
echo "$*" >>"$PWD/mise.calls"
|
||||
`,
|
||||
);
|
||||
|
||||
writeExecutable(
|
||||
join(workdir, 'bin/uv'),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
echo "$*" >>"$PWD/uv.calls"
|
||||
|
||||
if [[ "\${1:-}" != "version" ]]; then
|
||||
echo "Unexpected uv command: $*" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
directory="."
|
||||
|
||||
if [[ "\${1:-}" == "--directory" ]]; then
|
||||
directory="$2"
|
||||
shift 2
|
||||
fi
|
||||
|
||||
version="\${1:-}"
|
||||
mkdir -p "$directory"
|
||||
cat >"$directory/pyproject.toml" <<PYPROJECT
|
||||
[project]
|
||||
version = "$version"
|
||||
PYPROJECT
|
||||
`,
|
||||
);
|
||||
};
|
||||
|
||||
const assertCommandPassed = (result) => {
|
||||
assert.equal(result.status, 0, result.stderr || result.stdout);
|
||||
};
|
||||
|
||||
const assertPackageVersions = (fixture, expected) => {
|
||||
assert.equal(packageVersion(fixture.path), expected);
|
||||
assert.equal(packageVersion(fixture.file('server')), expected);
|
||||
assert.equal(packageVersion(fixture.file('packages/cli')), expected);
|
||||
assert.equal(packageVersion(fixture.file('web')), expected);
|
||||
assert.equal(packageVersion(fixture.file('e2e')), expected);
|
||||
assert.equal(packageVersion(fixture.file('packages/sdk')), expected);
|
||||
};
|
||||
|
||||
const npmCalls = (fixture) => fixture.readFile('npm.calls').trim().split('\n');
|
||||
|
||||
test('starts an RC from the server version when the root package is stale', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.0.0', mobileBuild: 3047 });
|
||||
|
||||
const result = fixture.run('-s', 'minor', '-m', 'true', '-r', 'true');
|
||||
|
||||
assertCommandPassed(result);
|
||||
assertPackageVersions(fixture, '3.1.0-rc.0');
|
||||
assert.ok(npmCalls(fixture).includes('version preminor --preid=rc --no-git-tag-version'));
|
||||
assert.match(fixture.readFile('mobile/pubspec.yaml'), /version: 3\.1\.0-rc\.0\+3048/);
|
||||
assert.match(fixture.readFile('mobile/android/fastlane/Fastfile'), /"android\.injected\.version\.name" => "3\.1\.0-rc\.0"/);
|
||||
assert.match(fixture.readFile('mobile/android/fastlane/Fastfile'), /"android\.injected\.version\.code" => 3048/);
|
||||
assert.match(fixture.readFile('mobile/ios/Runner/Info.plist'), /<string>3\.1\.0<\/string>/);
|
||||
assert.match(fixture.readFile('uv.calls'), /version --directory machine-learning 3\.1\.0rc0/);
|
||||
assert.equal(fixture.hasFile('archive-version.calls'), false);
|
||||
assert.match(fixture.readFile('github_env'), /IMMICH_VERSION=v3\.1\.0-rc\.0/);
|
||||
});
|
||||
|
||||
test('iterates an existing RC', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.1.0-rc.0', mobileBuild: 3048 });
|
||||
|
||||
const result = fixture.run('-m', 'false', '-r', 'true');
|
||||
|
||||
assertCommandPassed(result);
|
||||
assertPackageVersions(fixture, '3.1.0-rc.1');
|
||||
assert.ok(npmCalls(fixture).includes('version prerelease --no-git-tag-version'));
|
||||
assert.equal(npmCalls(fixture).some((call) => call.startsWith('version prerelease --preid')), false);
|
||||
assert.match(fixture.readFile('mobile/pubspec.yaml'), /version: 3\.1\.0-rc\.1\+3048/);
|
||||
assert.match(fixture.readFile('uv.calls'), /version --directory machine-learning 3\.1\.0rc1/);
|
||||
assert.equal(fixture.hasFile('archive-version.calls'), false);
|
||||
});
|
||||
|
||||
test('finalizes an existing RC when rc is false', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.1.0-rc.1', mobileBuild: 3048 });
|
||||
|
||||
const result = fixture.run('-m', 'false', '-r', 'false');
|
||||
|
||||
assertCommandPassed(result);
|
||||
assertPackageVersions(fixture, '3.1.0');
|
||||
assert.match(fixture.readFile('mobile/pubspec.yaml'), /version: 3\.1\.0\+3048/);
|
||||
assert.match(fixture.readFile('mobile/ios/Runner/Info.plist'), /<string>3\.1\.0<\/string>/);
|
||||
assert.match(fixture.readFile('uv.calls'), /version --directory machine-learning 3\.1\.0/);
|
||||
assert.match(fixture.readFile('archive-version.calls'), /3\.1\.0/);
|
||||
});
|
||||
|
||||
test('bumps a normal patch release', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.1.0', mobileBuild: 3048 });
|
||||
|
||||
const result = fixture.run('-s', 'patch', '-m', 'true');
|
||||
|
||||
assertCommandPassed(result);
|
||||
assertPackageVersions(fixture, '3.1.1');
|
||||
assert.match(fixture.readFile('mobile/pubspec.yaml'), /version: 3\.1\.1\+3049/);
|
||||
assert.match(fixture.readFile('uv.calls'), /version --directory machine-learning 3\.1\.1/);
|
||||
assert.match(fixture.readFile('archive-version.calls'), /3\.1\.1/);
|
||||
});
|
||||
|
||||
test('bumps mobile only', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.1.0', mobileBuild: 3048 });
|
||||
|
||||
const result = fixture.run('-m', 'true');
|
||||
|
||||
assertCommandPassed(result);
|
||||
assert.equal(packageVersion(fixture.path), '2.7.5');
|
||||
assert.equal(packageVersion(fixture.file('server')), '3.1.0');
|
||||
assert.match(fixture.readFile('mobile/pubspec.yaml'), /version: 3\.1\.0\+3049/);
|
||||
assert.equal(fixture.hasFile('uv.calls'), false);
|
||||
assert.equal(fixture.hasFile('archive-version.calls'), false);
|
||||
});
|
||||
|
||||
test('rejects a server bump while on an RC', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.1.0-rc.0', mobileBuild: 3048 });
|
||||
|
||||
const result = fixture.run('-s', 'patch', '-r', 'true');
|
||||
|
||||
assert.notEqual(result.status, 0);
|
||||
assert.match(result.stdout, /Cannot bump server while on an RC/);
|
||||
assert.equal(packageVersion(fixture.path), '2.7.5');
|
||||
assert.equal(packageVersion(fixture.file('server')), '3.1.0-rc.0');
|
||||
});
|
||||
|
||||
test('rejects a server bump while finalizing an RC', (t) => {
|
||||
const fixture = makeFixture(t, { rootVersion: '2.7.5', serverVersion: '3.1.0-rc.1', mobileBuild: 3048 });
|
||||
|
||||
const result = fixture.run('-s', 'patch', '-r', 'false');
|
||||
|
||||
assert.notEqual(result.status, 0);
|
||||
assert.match(result.stdout, /Cannot bump server while on an RC/);
|
||||
assert.equal(packageVersion(fixture.file('server')), '3.1.0-rc.1');
|
||||
});
|
||||
Reference in New Issue
Block a user