Skip to content

Commit 9bed120

Browse files
committed
Add about app in app menu.
1 parent 8ae4773 commit 9bed120

30 files changed

Lines changed: 676 additions & 44 deletions

.github/workflows/build-spa.yml

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
name: Build SPA
22

33
on:
4-
workflow_dispatch:
54
workflow_call:
5+
workflow_dispatch:
66

77
jobs:
8+
metadata:
9+
uses: ./.github/workflows/compute-build-metadata.yml
10+
with:
11+
version_policy: release
12+
813
build:
914
name: Build SPA static export
15+
needs: metadata
1016
runs-on: ubuntu-latest
1117
permissions:
1218
contents: write
1319
env:
14-
SHORT_SHA: ""
15-
ARTIFACT_NAME: ""
16-
TARBALL_NAME: ""
17-
RELEASE_TAG: ""
20+
APP_RELEASE_DATE: ${{ needs.metadata.outputs.app_release_date }}
21+
APP_VERSION: ${{ needs.metadata.outputs.app_version }}
22+
ARTIFACT_NAME: subsonic-player-static-${{ needs.metadata.outputs.short_sha }}
23+
RELEASE_TAG: ${{ needs.metadata.outputs.short_sha }}
24+
SHORT_SHA: ${{ needs.metadata.outputs.short_sha }}
25+
TARBALL_NAME: subsonic-player-static-${{ needs.metadata.outputs.short_sha }}.tar.gz
1826

1927
steps:
2028
- name: Checkout branch 🛎
@@ -23,17 +31,6 @@ jobs:
2331
fetch-depth: 0
2432
fetch-tags: true
2533

26-
- name: Set version metadata 🏷️
27-
run: |
28-
SHORT_SHA=$(git rev-parse --short HEAD)
29-
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
30-
echo "ARTIFACT_NAME=subsonic-player-static-${SHORT_SHA}" >> $GITHUB_ENV
31-
echo "TARBALL_NAME=subsonic-player-static-${SHORT_SHA}.tar.gz" >> $GITHUB_ENV
32-
33-
- name: Compute release tag 🏷️
34-
run: |
35-
echo "RELEASE_TAG=${SHORT_SHA}" >> $GITHUB_ENV
36-
3734
- name: Generate release notes 📝
3835
run: |
3936
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
@@ -60,6 +57,8 @@ jobs:
6057
run: yarn generate
6158
env:
6259
SPA_MODE: "true"
60+
APP_RELEASE_DATE: ${{ env.APP_RELEASE_DATE }}
61+
APP_VERSION: ${{ env.APP_VERSION }}
6362

6463
- name: Package artifacts 🗜️
6564
run: |
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Compute Build Metadata
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
version_policy:
7+
description: Version policy to use (preview or release)
8+
required: true
9+
type: string
10+
outputs:
11+
app_release_date:
12+
description: App release date in dd-mm-yyyy format
13+
value: ${{ jobs.compute.outputs.app_release_date }}
14+
app_version:
15+
description: Resolved app version
16+
value: ${{ jobs.compute.outputs.app_version }}
17+
short_sha:
18+
description: Short commit SHA
19+
value: ${{ jobs.compute.outputs.short_sha }}
20+
21+
jobs:
22+
compute:
23+
runs-on: ubuntu-latest
24+
outputs:
25+
app_release_date: ${{ steps.metadata.outputs.app_release_date }}
26+
app_version: ${{ steps.metadata.outputs.app_version }}
27+
short_sha: ${{ steps.metadata.outputs.short_sha }}
28+
29+
steps:
30+
- name: Checkout branch 🛎
31+
uses: actions/checkout@v6
32+
with:
33+
fetch-depth: 0
34+
fetch-tags: true
35+
36+
- name: Compute metadata 🏷️
37+
id: metadata
38+
env:
39+
VERSION_POLICY: ${{ inputs.version_policy }}
40+
run: |
41+
SHORT_SHA=$(git rev-parse --short HEAD)
42+
APP_RELEASE_DATE=$(date +%d-%m-%Y)
43+
TAG_VERSION=$(git describe --tags --exact-match 2>/dev/null || true)
44+
TAG_VERSION=${TAG_VERSION#v}
45+
46+
case "$VERSION_POLICY" in
47+
preview)
48+
APP_VERSION="$SHORT_SHA"
49+
;;
50+
release)
51+
if [ -n "$TAG_VERSION" ]; then
52+
APP_VERSION="$TAG_VERSION"
53+
else
54+
APP_VERSION="$SHORT_SHA"
55+
fi
56+
;;
57+
*)
58+
echo "Unsupported version-policy: $VERSION_POLICY"
59+
exit 1
60+
;;
61+
esac
62+
63+
echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
64+
echo "app_release_date=${APP_RELEASE_DATE}" >> "$GITHUB_OUTPUT"
65+
echo "app_version=${APP_VERSION}" >> "$GITHUB_OUTPUT"

.github/workflows/docker-publish-preview.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ env:
1717
APP_NAME: subsonic-player
1818

1919
jobs:
20+
metadata:
21+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
22+
uses: ./.github/workflows/compute-build-metadata.yml
23+
with:
24+
version_policy: preview
25+
2026
deploy:
27+
needs: metadata
2128
if: ${{ github.event.workflow_run.conclusion == 'success' }}
2229
runs-on: ubuntu-latest
2330

@@ -48,4 +55,6 @@ jobs:
4855
push: true
4956
build-args: |
5057
NODE_VERSION=${{ steps.node-version.outputs.version }}
58+
APP_RELEASE_DATE=${{ needs.metadata.outputs.app_release_date }}
59+
APP_VERSION=${{ needs.metadata.outputs.app_version }}
5160
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.APP_NAME }}:preview

.github/workflows/docker-publish.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ env:
88
APP_NAME: subsonic-player
99

1010
jobs:
11+
metadata:
12+
uses: ./.github/workflows/compute-build-metadata.yml
13+
with:
14+
version_policy: release
15+
1116
deploy:
17+
needs: metadata
1218
runs-on: ubuntu-latest
1319

1420
steps:
@@ -38,6 +44,8 @@ jobs:
3844
push: true
3945
build-args: |
4046
NODE_VERSION=${{ steps.node-version.outputs.version }}
47+
APP_RELEASE_DATE=${{ needs.metadata.outputs.app_release_date }}
48+
APP_VERSION=${{ needs.metadata.outputs.app_version }}
4149
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.APP_NAME }}:latest
4250

4351
- name: Update Docker description 📝

Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ WORKDIR /app
1313
# Create build stage.
1414
FROM base AS build
1515

16+
ARG APP_VERSION=dev
17+
ARG APP_RELEASE_DATE=
18+
19+
ENV APP_VERSION=${APP_VERSION}
20+
ENV APP_RELEASE_DATE=${APP_RELEASE_DATE}
21+
1622
# Copy package.json and yarn.lock files to the working directory.
1723
COPY ./package.json .
1824
COPY ./yarn.lock .
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import type { VueWrapper } from '@vue/test-utils';
2+
3+
import { mount } from '@vue/test-utils';
4+
5+
import { appInformationMock, serverInformationMock } from '@/test/fixtures';
6+
7+
import AboutApp from './AboutApp.vue';
8+
9+
function factory(props = {}) {
10+
return mount(AboutApp, {
11+
props: {
12+
appInformation: appInformationMock,
13+
serverInformation: serverInformationMock,
14+
...props,
15+
},
16+
});
17+
}
18+
19+
describe('AboutApp', () => {
20+
let wrapper: VueWrapper;
21+
22+
beforeEach(() => {
23+
wrapper = factory();
24+
});
25+
26+
it('matches the snapshot', () => {
27+
expect(wrapper.html()).toMatchSnapshot();
28+
});
29+
30+
describe('when the serverInformation prop name key is defined', () => {
31+
it('shows the server name element', () => {
32+
expect(wrapper.find({ ref: 'name' }).exists()).toBe(true);
33+
});
34+
});
35+
36+
describe('when the serverInformation prop name key is not defined', () => {
37+
beforeEach(() => {
38+
wrapper = factory({
39+
serverInformation: {
40+
...serverInformationMock,
41+
name: undefined,
42+
},
43+
});
44+
});
45+
46+
it('does not show the server name element', () => {
47+
expect(wrapper.find({ ref: 'name' }).exists()).toBe(false);
48+
});
49+
});
50+
51+
describe('when the serverInformation prop version key is defined', () => {
52+
it('shows the server version element', () => {
53+
expect(wrapper.find({ ref: 'version' }).exists()).toBe(true);
54+
});
55+
});
56+
57+
describe('when the serverInformation prop version key is not defined', () => {
58+
beforeEach(() => {
59+
wrapper = factory({
60+
serverInformation: {
61+
...serverInformationMock,
62+
version: undefined,
63+
},
64+
});
65+
});
66+
67+
it('does not show the server version element', () => {
68+
expect(wrapper.find({ ref: 'version' }).exists()).toBe(false);
69+
});
70+
});
71+
72+
describe('when the serverInformation prop openSubsonic key is defined', () => {
73+
it('shows the openSubsonic element', () => {
74+
expect(wrapper.find({ ref: 'openSubsonic' }).exists()).toBe(true);
75+
});
76+
});
77+
78+
describe('when the serverInformation prop openSubsonic key is not defined', () => {
79+
beforeEach(() => {
80+
wrapper = factory({
81+
serverInformation: {
82+
...serverInformationMock,
83+
openSubsonic: undefined,
84+
},
85+
});
86+
});
87+
88+
it('does not show the openSubsonic element', () => {
89+
expect(wrapper.find({ ref: 'openSubsonic' }).exists()).toBe(false);
90+
});
91+
});
92+
});

components/Molecules/AboutApp.vue

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<script setup lang="ts">
2+
defineProps<{
3+
appInformation: AppInformation;
4+
serverInformation: ServerInformation;
5+
}>();
6+
</script>
7+
8+
<template>
9+
<div :class="['mBXL', $style.aboutApp]">
10+
<h3 class="mBM">Server</h3>
11+
12+
<p v-if="serverInformation.name" ref="name">
13+
<span class="strong">Name: </span>
14+
{{ serverInformation.name }}
15+
</p>
16+
17+
<p v-if="serverInformation.version" ref="version">
18+
<span class="strong">Version: </span>
19+
{{ serverInformation.version }}
20+
</p>
21+
22+
<p>
23+
<span class="strong">URL: </span>
24+
25+
<a
26+
:href="serverInformation.url"
27+
rel="noopener noreferrer"
28+
target="_blank"
29+
>
30+
{{ serverInformation.url }}
31+
</a>
32+
</p>
33+
34+
<p v-if="serverInformation.openSubsonic" ref="openSubsonic">
35+
<span class="strong">OpenSubsonic enabled: </span>
36+
{{ serverInformation.openSubsonic }}
37+
</p>
38+
</div>
39+
40+
<div :class="$style.aboutApp">
41+
<h3 class="mBM">App</h3>
42+
43+
<p>
44+
<span class="strong">App version: </span>
45+
46+
<a
47+
:href="appInformation.githubReleaseUrl"
48+
rel="noopener noreferrer"
49+
target="_blank"
50+
>
51+
{{ appInformation.version }}
52+
</a>
53+
</p>
54+
55+
<p>
56+
<span class="strong">Released: </span>
57+
{{ appInformation.releaseDate }}
58+
</p>
59+
60+
<p>
61+
<a
62+
:href="appInformation.homepageUrl"
63+
rel="noopener noreferrer"
64+
target="_blank"
65+
>
66+
Subsonic Player
67+
</a>
68+
</p>
69+
70+
<p>
71+
<a
72+
:href="appInformation.githubUrl"
73+
rel="noopener noreferrer"
74+
target="_blank"
75+
>
76+
Source code
77+
</a>
78+
</p>
79+
80+
<p>
81+
<a
82+
:href="appInformation.bugReportUrl"
83+
rel="noopener noreferrer"
84+
target="_blank"
85+
>
86+
Bug reports
87+
</a>
88+
</p>
89+
</div>
90+
</template>
91+
92+
<style module>
93+
.aboutApp {
94+
text-align: center;
95+
96+
a {
97+
color: var(--theme-color);
98+
}
99+
}
100+
101+
.title {
102+
min-width: 25%;
103+
}
104+
</style>

0 commit comments

Comments
 (0)