Skip to content
2 changes: 1 addition & 1 deletion app/components/AppFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const isHome = computed(() => route.name === 'index')
>
<div>
<p class="font-mono text-balance m-0 hidden sm:block">{{ $t('tagline') }}</p>
<BuildEnvironment v-if="!isHome" footer />
</div>
<!-- Desktop: Show all links. Mobile: Links are in MobileMenu -->
<div class="hidden sm:flex items-center gap-6">
Expand Down Expand Up @@ -56,6 +55,7 @@ const isHome = computed(() => route.name === 'index')
</a>
</div>
</div>
<BuildEnvironment v-if="!isHome" footer />
<p class="text-xs text-fg-muted text-center sm:text-start m-0">
<span class="sm:hidden">{{ $t('non_affiliation_disclaimer') }}</span>
<span class="hidden sm:inline">{{ $t('trademark_disclaimer') }}</span>
Expand Down
10 changes: 7 additions & 3 deletions app/components/BuildEnvironment.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<script setup lang="ts">
defineProps<{
import type { BuildInfo } from '#shared/types'

const { footer = false, buildInfo: buildInfoProp } = defineProps<{
footer?: boolean
buildInfo?: BuildInfo
}>()

const { locale } = useI18n()
const buildInfo = useAppConfig().buildInfo
const appConfig = useAppConfig()
const buildInfo = computed(() => buildInfoProp || appConfig.buildInfo)
</script>

<template>
<div
class="font-mono text-xs text-fg-muted flex items-center gap-2 motion-safe:animate-fade-in motion-safe:animate-fill-both"
:class="footer ? 'mt-4 justify-start' : 'mb-8 justify-center'"
:class="footer ? 'my-1 justify-center sm:justify-start' : 'mb-8 justify-center'"
style="animation-delay: 0.05s"
>
<i18n-t keypath="built_at" scope="global">
Expand Down
35 changes: 24 additions & 11 deletions modules/build-env.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BuildInfo } from '../shared/types'
import type { BuildInfo, EnvType } from '../shared/types'
import { createResolver, defineNuxtModule } from 'nuxt/kit'
import { isCI } from 'std-env'
import { getEnv, version } from '../config/env'
Expand All @@ -10,18 +10,31 @@ export default defineNuxtModule({
name: 'npmx:build-env',
},
async setup(_options, nuxt) {
const { env, commit, shortCommit, branch } = await getEnv(nuxt.options.dev)

let env: EnvType = 'dev'
nuxt.options.appConfig = nuxt.options.appConfig || {}
nuxt.options.appConfig.env = env
nuxt.options.appConfig.buildInfo = {
version,
time: +Date.now(),
commit,
shortCommit,
branch,
env,
} satisfies BuildInfo
if (process.env.TEST) {
nuxt.options.appConfig.buildInfo = {
env,
version: '0.0.0',
commit: '704987bba88909f3782d792c224bde989569acb9',
shortCommit: '704987b',
branch: 'xxx',
time: 1770237446424,
} satisfies BuildInfo
} else {
const { env: useEnv, commit, shortCommit, branch } = await getEnv(nuxt.options.dev)
env = useEnv
nuxt.options.appConfig.env = useEnv
nuxt.options.appConfig.buildInfo = {
version,
time: +Date.now(),
commit,
shortCommit,
branch,
env,
} satisfies BuildInfo
}

nuxt.options.nitro.publicAssets = nuxt.options.nitro.publicAssets || []
if (env === 'dev') nuxt.options.nitro.publicAssets.unshift({ dir: resolve('../public-dev') })
Expand Down
4 changes: 3 additions & 1 deletion shared/types/env.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export type EnvType = 'dev' | 'preview' | 'canary' | 'release'

export interface BuildInfo {
version: string
commit: string
shortCommit: string
time: number
branch: string
env: 'preview' | 'canary' | 'dev' | 'release'
env: EnvType
}
35 changes: 35 additions & 0 deletions test/nuxt/components/AppFooter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, expect, it } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
import AppFooter from '~/components/AppFooter.vue'

/* check nuxt module at modules/build-env.ts */
describe('AppFooter', () => {
it('BuildEnvironment is properly displayed at settings', async () => {
const buildInfo = useAppConfig().buildInfo
const component = await mountSuspended(AppFooter, {
route: '/settings',
})

const envSpan = component.find('span.tracking-wider')
expect(envSpan.exists()).toBe(true)
expect(envSpan.text()).toBe(buildInfo.env)
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
expect(commitLink.exists()).toBe(true)
const tagLink = component.find(`a[href$="/tag/v${buildInfo.commit}"]`)
expect(tagLink.exists()).toBe(false)
})

it('BuildEnvironment is hidden at home', async () => {
const buildInfo = useAppConfig().buildInfo
const component = await mountSuspended(AppFooter, {
route: '/',
})

const envSpan = component.find('span.tracking-wider')
expect(envSpan.exists()).toBe(false)
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
expect(commitLink.exists()).toBe(false)
const tagLink = component.find(`a[href$="/tag/v${buildInfo.commit}"]`)
expect(tagLink.exists()).toBe(false)
})
})
56 changes: 56 additions & 0 deletions test/nuxt/components/BuildEnvironment.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { BuildInfo } from '#shared/types'
import { describe, expect, it } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
import BuildEnvironment from '~/components/BuildEnvironment.vue'

describe('BuildEnvironment', () => {
it('renders dev environment correctly', async () => {
const buildInfo: BuildInfo = {
env: 'dev',
version: '1.2.3',
time: 1234567890,
commit: 'abcdef',
shortCommit: 'abc',
branch: 'main',
}
const component = await mountSuspended(BuildEnvironment, {
props: {
buildInfo,
},
})

// In dev mode, it shows env name, not version link
const envSpan = component.find('span.tracking-wider')
expect(envSpan.exists()).toBe(true)
expect(envSpan.text()).toBe(buildInfo.env)
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
expect(commitLink.exists()).toBe(true)
const tagLink = component.find(`a[href$="/tag/v${buildInfo.commit}"]`)
expect(tagLink.exists()).toBe(false)
})

it('renders release environment correctly', async () => {
const buildInfo: BuildInfo = {
env: 'release',
version: '1.2.3',
time: 1234567890,
commit: 'abcdef',
shortCommit: 'abc',
branch: 'release',
}

const component = await mountSuspended(BuildEnvironment, {
props: {
buildInfo,
},
})

// In release mode, it shows tag version link, not env name
const envSpan = component.find('span.tracking-wider')
expect(envSpan.exists()).toBe(false)
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
expect(commitLink.exists()).toBe(false)
const tagLink = component.find(`a[href$="/tag/v${buildInfo.version}"]`)
expect(tagLink.exists()).toBe(true)
})
})
Loading