The source offer is a link to this fork, not a tarball beside the app (#7)

INBUXA Admin built its own source into every deployment: the whole tree
packed as source.tar.gz next to the app, with an identity string shown
beside the link and in the version tooltip. The top bar menu and the
source link offered that download.

It answered the AGPL precisely -- the source of *this* build, uncommitted
work and all -- but it paid for that by carrying the tree into every
deployment, to a repository that is public and already has it. The
version shown beside the link already names the build, so the link and
the version together say what the archive said.

This is the same change already made to ihasmail-inbuxa, for the same
reason, and it leaves the two forks answering the offer the same way.

It is also what lets INBUXA Admin be built in an Alpine image: the
plugin shelled out to `tar --transform`, which BusyBox tar does not
have, so `npm run build` failed there and nowhere else.

Removed with it: source-archive.ts, the Vite plugin call, __SOURCE_ID__
and sourceDownloadUrl(). The build no longer shells out to git or tar,
and nothing is written next to the app.

The two strings that named the archive change with it: the link now
reads "Source code (<version>), AGPL-3.0" rather than naming a tree id,
and the version tooltip drops the id it appended.
This commit is contained in:
jcoffey
2026-09-20 16:10:27 -07:00
committed by GitHub
parent fa42a74697
commit 4720470a3d
6 changed files with 17 additions and 91 deletions
+5 -5
View File
@@ -5,17 +5,17 @@
*/
import { useTranslation } from 'react-i18next';
import { sourceDownloadUrl } from '@/lib/sourceDownload';
import { SOURCE_URL } from '@/lib/sourceDownload';
/**
* The AGPL's offer to everyone using this interface over the network: the
* exact source of the version running, with that version named.
* The AGPL's offer to everyone using this interface over the network: where
* the source is, with the running version named beside it.
*/
export function SourceLink({ className }: { className?: string }) {
const { t } = useTranslation();
return (
<a href={sourceDownloadUrl()} target="_blank" rel="noopener noreferrer" className={className}>
{t('source.download', 'Source code of this version ({{id}}), AGPL-3.0', { id: __SOURCE_ID__ })}
<a href={SOURCE_URL} target="_blank" rel="noopener noreferrer" className={className}>
{t('source.download', 'Source code ({{version}}), AGPL-3.0', { version: __APP_VERSION__ })}
</a>
);
}
+3 -3
View File
@@ -31,7 +31,7 @@ import { isPaletteId, PALETTES } from '@/lib/palettes';
import Logo from '@/components/common/Logo';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { EnterpriseUpsell } from '@/components/common/EnterpriseUpsell';
import { sourceDownloadUrl } from '@/lib/sourceDownload';
import { SOURCE_URL } from '@/lib/sourceDownload';
import { visibleLayouts } from '@/lib/layout';
import { sectionLandingLink } from '@/lib/lastVisited';
import { cn } from '@/lib/utils';
@@ -104,7 +104,7 @@ export function TopBar() {
</Link>
</TooltipTrigger>
<TooltipContent side="bottom">
{t('version.label', 'INBUXA Admin {{version}}', { version: __APP_VERSION__ })} · {__SOURCE_ID__}
{t('version.label', 'INBUXA Admin {{version}}', { version: __APP_VERSION__ })}
</TooltipContent>
</Tooltip>
</TooltipProvider>
@@ -286,7 +286,7 @@ export function TopBar() {
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<a href={sourceDownloadUrl()} target="_blank" rel="noopener noreferrer">
<a href={SOURCE_URL} target="_blank" rel="noopener noreferrer">
<FileCode className="mr-2 h-4 w-4" />
{t('source.menu', 'Source code (AGPL-3.0)')}
</a>
+8 -6
View File
@@ -4,9 +4,11 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { getBasePath } from '@/lib/basePath';
/** Where this build's own source is: written next to the app at build time (see source-archive.ts). */
export function sourceDownloadUrl(): string {
return `${getBasePath()}/source.tar.gz`;
}
/**
* Where to point someone who wants this interface's source.
*
* INBUXA Admin is a modified Stalwart web interface, so the AGPL's offer is
* this fork. The version shown beside the link names the build, which is what
* makes the offer something a person can act on.
*/
export const SOURCE_URL = 'https://github.com/inbuxa/inbuxa-admin';
-1
View File
@@ -22,4 +22,3 @@ interface ImportMeta {
}
declare const __APP_VERSION__: string;
declare const __SOURCE_ID__: string;