fix(release): every snap packed without --output, into its project, then moved

snapcraft builds in LXD with the project mounted at /root/project and refuses
any --output naming a folder of this machine: the root's own build/release/
for Learn's snap (found releasing Learn 0.23.0) as the clone itself for Todo's
and Train's (Todo 0.1.0, both 3 Nov 2026). Every snap now packs into its
project and is moved into the release's folder from there, checked with
snapcraft 9.2.1 at the root. A failure after none of several apps was done
now says "none" rather than nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-03 18:59:40 +01:00
commit 8565db3d89
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
4 changed files with 25 additions and 44 deletions

View file

@ -152,31 +152,22 @@ void main() {
); );
}); });
test( test("Learn's snap is the root's; Todo's and Train's are built in clones of "
"Learn's snap is the root's; Todo's and Train's are built in clones of " 'their own, outside the repository', () {
'their own, outside the repository, and packed without --output, as ' expect(learnRelease.snap!.atRoot, isTrue);
"snapcraft takes the clone's own path for a file outside the project", for (final (app, name) in [
() { (todoRelease, 'halkyon-todo'),
expect(learnRelease.snap!.atRoot, isTrue); (trainRelease, 'halkyon-train'),
]) {
final snap = app.snap!;
expect(snap.atRoot, isFalse, reason: app.id);
expect( expect(
learnRelease.snap!.packOutput(root: '/repo', out: 'build/x'), snap.projectPath('/home/someone'),
'/repo/build/x', '/home/someone/.cache/halkyon-release/snap/$name',
); );
for (final (app, name) in [ expect(snap.storeChannel, 'edge', reason: app.id);
(todoRelease, 'halkyon-todo'), }
(trainRelease, 'halkyon-train'), });
]) {
final snap = app.snap!;
expect(snap.atRoot, isFalse, reason: app.id);
expect(
snap.projectPath('/home/someone'),
'/home/someone/.cache/halkyon-release/snap/$name',
);
expect(snap.packOutput(root: '/repo', out: 'build/x'), isNull);
expect(snap.storeChannel, 'edge', reason: app.id);
}
},
);
for (final app in [todoRelease, trainRelease]) { for (final app in [todoRelease, trainRelease]) {
group("${app.name}'s snap, built in a clone of its own with its folder in " group("${app.name}'s snap, built in a clone of its own with its folder in "

View file

@ -101,8 +101,8 @@ Future<void> main(List<String> arguments) async {
stderr.writeln('✗ $failure'); stderr.writeln('✗ $failure');
if (targets.length > 1) { if (targets.length > 1) {
stderr.writeln( stderr.writeln(
' Done before it: ${done.map((t) => t.app).join(', ')}; not ' ' Done before it: ${done.isEmpty ? 'none' : done.map((t) => t.app).join(', ')}; '
'started: ${targets.skip(done.length + 1).map((t) => t.app).join(', ')}.', 'not started: ${targets.skip(done.length + 1).map((t) => t.app).join(', ')}.',
); );
} }
exit(1); exit(1);

View file

@ -215,13 +215,4 @@ final class const SnapRelease({
/// does for the root's, and outside the repository, which the checks would /// does for the root's, and outside the repository, which the checks would
/// otherwise analyse. /// otherwise analyse.
String projectPath(String home) => '$home/.cache/halkyon-release/snap/$name'; String projectPath(String home) => '$home/.cache/halkyon-release/snap/$name';
/// The folder `snapcraft pack --output` names: the release's folder ([out]
/// in [root]) for the root's; none for any other, which snapcraft then packs
/// into its clone, where the release tool takes it from. snapcraft builds in
/// LXD with the project mounted elsewhere, and takes an `--output` naming the
/// clone itself for a file in the folder above it, outside the project, so
/// refuses it (found releasing Todo 0.1.0, 3 Nov 2026).
String? packOutput({required String root, required String out}) =>
atRoot ? '$root/$out' : null;
} }

View file

@ -454,16 +454,15 @@ final class Releaser({
'clean', 'clean',
snap.part, snap.part,
], workingDirectory: project); ], workingDirectory: project);
final output = snap.packOutput(root: root.path, out: out); // Packed without --output, into the project, and moved from there:
await _run('snapcraft', [ // snapcraft builds in LXD with the project mounted elsewhere and
'pack', // refuses any --output naming a folder of this machine, the root's
if (output != null) ...['--output', output], // own build/ (found releasing Learn 0.23.0) as a clone's (Todo 0.1.0,
], workingDirectory: project); // both 3 Nov 2026).
if (output == null) { await _run('snapcraft', ['pack'], workingDirectory: project);
File(p.join(project, snapFile)) File(p.join(project, snapFile))
..copySync(p.join(root.path, out, snapFile)) ..copySync(p.join(root.path, out, snapFile))
..deleteSync(); ..deleteSync();
}
await _checkSnap(p.join(out, snapFile), version); await _checkSnap(p.join(out, snapFile), version);
} }