mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 22:26:16 -08:00
feat(about): show build commit next to the app version
Settings > About now renders "<version> (<short-sha>)" with the full SHA in the tooltip, so bug reports from test and nightly builds identify the exact commit. The commit is injected at CI build time into apps/web/src/environments/build-commit.ts (same placeholder pattern as the TMDB key inject); PR builds use the real head SHA instead of the ephemeral merge commit. Local/dev builds keep the plain version. The semver version itself deliberately stays untouched: a "-sha" suffix would flip electron-updater into prerelease mode and leak into installer/artifact version fields. Requested by WolfganP in #1202. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2f8aee72df
commit
2546bb9bfd
9 files changed
+155
-2
No files matched your search
@@ -19,7 +19,17 @@
|
||||
<p>{{ 'SETTINGS.VERSION_DESCRIPTION' | translate }}</p>
|
||||
</div>
|
||||
<div class="setting-item__control version-block">
|
||||
<span>{{ version() }}</span>
|
||||
<span data-test-id="app-version">
|
||||
{{ version() }}
|
||||
@if (buildCommitShort(); as commit) {
|
||||
<span
|
||||
class="build-commit"
|
||||
data-test-id="app-build-commit"
|
||||
[title]="buildCommit()"
|
||||
>({{ commit }})</span
|
||||
>
|
||||
}
|
||||
</span>
|
||||
<small>{{ updateMessage() }}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -132,3 +132,60 @@ describe('SettingsAboutSectionComponent app updates', () => {
|
||||
expect(getButton(fixture, 'app-update-open-release')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('SettingsAboutSectionComponent version display', () => {
|
||||
let fixture: ComponentFixture<SettingsAboutSectionComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [
|
||||
SettingsAboutSectionComponent,
|
||||
TranslateModule.forRoot(),
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SettingsAboutSectionComponent);
|
||||
fixture.componentRef.setInput('activeSection', 'about');
|
||||
fixture.componentRef.setInput('version', '0.23.0');
|
||||
});
|
||||
|
||||
function getVersionBlock() {
|
||||
return fixture.nativeElement.querySelector(
|
||||
'[data-test-id="app-version"]'
|
||||
) as HTMLElement;
|
||||
}
|
||||
|
||||
function getCommitMarker() {
|
||||
return fixture.nativeElement.querySelector(
|
||||
'[data-test-id="app-build-commit"]'
|
||||
) as HTMLElement | null;
|
||||
}
|
||||
|
||||
it('shows the shortened build commit next to the version on CI builds', () => {
|
||||
fixture.componentRef.setInput(
|
||||
'buildCommit',
|
||||
'949ea520aa11bb22cc33dd44ee55ff6677889900'
|
||||
);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getVersionBlock().textContent).toContain('0.23.0');
|
||||
expect(getCommitMarker()?.textContent).toBe('(949ea52)');
|
||||
expect(getCommitMarker()?.getAttribute('title')).toBe(
|
||||
'949ea520aa11bb22cc33dd44ee55ff6677889900'
|
||||
);
|
||||
});
|
||||
|
||||
it('shows the plain version when no build commit was injected', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getVersionBlock().textContent).toContain('0.23.0');
|
||||
expect(getCommitMarker()).toBeNull();
|
||||
});
|
||||
|
||||
it('treats a whitespace-only commit as absent', () => {
|
||||
fixture.componentRef.setInput('buildCommit', ' ');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getCommitMarker()).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -18,15 +18,25 @@ import {
|
||||
imports: [MatButtonModule, MatIconModule, TranslateModule],
|
||||
templateUrl: './settings-about-section.component.html',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
styles: [':host { display: contents; }'],
|
||||
styles: [
|
||||
':host { display: contents; }',
|
||||
'.version-block .build-commit { opacity: 0.65; font-size: 0.85em; }',
|
||||
],
|
||||
})
|
||||
export class SettingsAboutSectionComponent {
|
||||
readonly activeSection = input.required<string>();
|
||||
readonly isDesktop = input(false);
|
||||
readonly version = input<string | undefined>();
|
||||
readonly buildCommit = input<string | undefined>();
|
||||
readonly updateMessage = input<string | undefined>();
|
||||
readonly appUpdateStatus = input<ElectronBridgeAppUpdateStatus | null>(null);
|
||||
|
||||
readonly buildCommitShort = computed(() => {
|
||||
const commit = this.buildCommit()?.trim();
|
||||
|
||||
return commit ? commit.slice(0, 7) : undefined;
|
||||
});
|
||||
|
||||
readonly checkForAppUpdate = output<void>();
|
||||
readonly downloadAppUpdate = output<void>();
|
||||
readonly installAppUpdate = output<void>();
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
[activeSection]="activeSection()"
|
||||
[isDesktop]="isDesktop"
|
||||
[version]="version"
|
||||
[buildCommit]="buildCommit"
|
||||
[updateMessage]="updateMessage"
|
||||
[appUpdateStatus]="appUpdateStatus()"
|
||||
(checkForAppUpdate)="checkForAppUpdate()"
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
selectIsEpgAvailable,
|
||||
} from '@iptvnator/m3u-state';
|
||||
import { take } from 'rxjs';
|
||||
import { BUILD_COMMIT } from '../../environments/build-commit';
|
||||
import { DataService, RuntimeCapabilitiesService } from '@iptvnator/services';
|
||||
import {
|
||||
EmbeddedMpvSupport,
|
||||
@@ -200,6 +201,9 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
/** Current version of the app */
|
||||
version = '';
|
||||
|
||||
/** Git commit the app was built from (CI builds only) */
|
||||
readonly buildCommit = BUILD_COMMIT;
|
||||
|
||||
/** Update message to show */
|
||||
updateMessage = '';
|
||||
readonly appUpdateStatus = signal<ElectronBridgeAppUpdateStatus | null>(
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Git commit the app was built from. Populated by
|
||||
* tools/build/inject-build-commit.mjs during CI builds; stays empty for
|
||||
* local/dev builds, in which case Settings > About shows the plain version.
|
||||
*
|
||||
* Intentionally separate from AppConfig.version: appending the SHA to the
|
||||
* semver itself would flip electron-updater into prerelease mode and leak
|
||||
* into installer/artifact version fields.
|
||||
*/
|
||||
export const BUILD_COMMIT = '';
|
||||
Reference in new issue
Block a user