fix(release): a snap built in a clone of its own is packed without --output, into the clone
All checks were successful
CI / check (push) Successful in 40m26s
CI / deploy (push) Successful in 1m4s

snapcraft builds in LXD with the project mounted at /root/project and passes --output
on unchanged: naming the clone itself, it took the clone for a file in the folder above,
outside the project, and refused it again. Without --output it packs into the clone
(checked with snapcraft 9.2.1 in Todo's clone), from where the release tool moves it.

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 10:31:05 +01:00
commit c8d94d0ceb
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
3 changed files with 17 additions and 29 deletions

View file

@ -167,18 +167,12 @@ void main() {
);
});
test('is packed inside its clone, as snapcraft packs nowhere outside the '
"project, and Learn's into the release's folder", () {
test('is packed without --output, into its clone, as snapcraft takes the '
"clone's own path for a file outside the project; Learn's into the "
"release's folder", () {
expect(snap.packOutput(root: '/repo', out: 'build/x'), isNull);
expect(
snap.packPath(home: '/home/someone', root: '/repo', out: 'build/x'),
'/home/someone/.cache/halkyon-release/snap/halkyon-todo',
);
expect(
learnRelease.snap!.packPath(
home: '/home/someone',
root: '/repo',
out: 'build/x',
),
learnRelease.snap!.packOutput(root: '/repo', out: 'build/x'),
'/repo/build/x',
);
});

View file

@ -216,13 +216,12 @@ final class const SnapRelease({
/// otherwise analyse.
String projectPath(String home) => '$home/.cache/halkyon-release/snap/$name';
/// Where `snapcraft pack` writes the snap: the release's folder ([out] in
/// [root]) for the root's, its clone for any other, as snapcraft packs
/// nowhere outside the project it builds (found releasing Todo 0.1.0, 3 Nov
/// 2026); the release tool moves it into the release's folder from there.
String packPath({
required String home,
required String root,
required String out,
}) => atRoot ? '$root/$out' : projectPath(home);
/// 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,18 +454,13 @@ final class Releaser({
'clean',
snap.part,
], workingDirectory: project);
final packed = snap.packPath(
home: Platform.environment['HOME'] ?? '',
root: root.path,
out: out,
);
final output = snap.packOutput(root: root.path, out: out);
await _run('snapcraft', [
'pack',
'--output',
packed,
if (output != null) ...['--output', output],
], workingDirectory: project);
if (!snap.atRoot) {
File(p.join(packed, snapFile))
if (output == null) {
File(p.join(project, snapFile))
..copySync(p.join(root.path, out, snapFile))
..deleteSync();
}