Version in self hosted (#770)

* Enhance Application Version Management in Docker and Feature Flags

- Added a new build argument `APP_VERSION` in the Docker configuration files to facilitate version tracking during builds.
- Introduced a private method `getAppVersion` in `FeatureFlagsController` to retrieve the application version from the Docker environment, enhancing the feature flags response with version information.
- Updated the `app.php` configuration file to include a new entry for `docker_version`, allowing for better version management and fallback when the Docker build version is unavailable.

These changes aim to improve the application's versioning capabilities, ensuring that the version is consistently available across different components and environments.

* Refactor OpenFormFooter and Update Feature Flags Handling

- Modified `OpenFormFooter.vue` to include a version display when available, enhancing user awareness of the application version.
- Refactored the script section to use the `<script setup>` syntax, improving readability and reactivity by utilizing `ref` and `computed` for reactive properties.
- Removed the deprecated `feature-flags.js` plugin and updated `featureFlags.js` to ensure proper SSR compatibility and error handling during feature flag fetching.

These changes aim to improve the user interface by providing version information and enhance the overall code structure for better maintainability and performance.
This commit is contained in:
Julien Nahum 2025-05-27 17:44:42 +02:00 committed by GitHub
parent a030a84652
commit f3a02df80e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 68 additions and 38 deletions

View File

@ -60,6 +60,7 @@ jobs:
build-args: |
APP_ENV=${{ env.VERSION == 'dev' && 'local' || 'production' }}
COMPOSER_FLAGS=${{ env.VERSION == 'dev' && '--optimize-autoloader --no-interaction' || '--no-dev --optimize-autoloader --no-interaction' }}
APP_VERSION=${{ env.VERSION }}
tags: ${{ env.API_TAGS }}
cache-from: type=registry,ref=${{secrets.DOCKER_API_REPO}}:dev
cache-to: type=inline
@ -71,6 +72,8 @@ jobs:
file: docker/Dockerfile.client
platforms: linux/amd64,linux/arm64
push: true
build-args: |
APP_VERSION=${{ env.VERSION }}
tags: ${{ env.UI_TAGS }}
cache-from: type=registry,ref=${{secrets.DOCKER_UI_REPO}}:dev
cache-to: type=inline

View File

@ -14,6 +14,7 @@ class FeatureFlagsController extends Controller
'self_hosted' => config('app.self_hosted', true),
'custom_domains' => config('custom-domains.enabled', false),
'ai_features' => !empty(config('services.openai.api_key')),
'version' => $this->getAppVersion(),
'billing' => [
'enabled' => !empty(config('cashier.key')) && !empty(config('cashier.secret')),
@ -44,4 +45,17 @@ class FeatureFlagsController extends Controller
return response()->json($featureFlags);
}
/**
* Get the application version from Docker environment or fallback
*/
private function getAppVersion(): ?string
{
// Only return version for self-hosted installations
if (!config('app.self_hosted', true)) {
return null;
}
return config('app.docker_version');
}
}

View File

@ -15,6 +15,17 @@ return [
'name' => env('APP_NAME', 'OpnForm'),
/*
|--------------------------------------------------------------------------
| Application Version
|--------------------------------------------------------------------------
|
| This value is the version of your application. Used for display purposes
| and fallback when Docker build version is not available.
|
*/
'docker_version' => env('APP_VERSION_DOCKER'),
/*
|--------------------------------------------------------------------------
| Application Environment

View File

@ -4,6 +4,9 @@
<div class="flex mt-2 items-center">
<p class="text-sm text-gray-600 dark:text-gray-400 text-center w-full">
© Copyright {{ currYear }}. All Rights Reserved
<span v-if="version">
<br>Version {{ version }}
</span>
</p>
</div>
<div class="flex justify-center mt-5 md:mt-0">
@ -82,22 +85,14 @@
</div>
</template>
<script>
import { computed } from "vue"
<script setup>
import opnformConfig from "~/opnform.config.js"
export default {
setup() {
const authStore = useAuthStore()
return {
user: computed(() => authStore.user),
appStore: useAppStore(),
opnformConfig,
}
},
data: () => ({
currYear: new Date().getFullYear(),
}),
}
const user = computed(() => authStore.user)
const currYear = ref(new Date().getFullYear())
// Use the reactive version for proper template reactivity
const version = computed(() => useFeatureFlag('version'))
</script>

View File

@ -1,11 +1,5 @@
export default defineNuxtRouteMiddleware(async () => {
const authStore = useAuthStore()
const featureFlagsStore = useFeatureFlagsStore()
// Ensure feature flags are loaded
if (!featureFlagsStore.isLoaded) {
await featureFlagsStore.fetchFlags()
}
if (useFeatureFlag('self_hosted')) {
if (authStore.check && authStore.user?.email === 'admin@opnform.com') {

View File

@ -1,10 +0,0 @@
import { useFeatureFlagsStore } from '~/stores/featureFlags'
export default defineNuxtPlugin(async () => {
const featureFlagsStore = useFeatureFlagsStore()
// Load flags if they haven't been loaded yet
if (!featureFlagsStore.isLoaded) {
await featureFlagsStore.fetchFlags()
}
})

View File

@ -1,9 +1,18 @@
import { useFeatureFlagsStore } from '~/stores/featureFlags'
export default defineNuxtPlugin((nuxtApp) => {
const featureFlagsStore = useFeatureFlagsStore()
export default defineNuxtPlugin(async (nuxtApp) => {
// Get the pinia instance for SSR compatibility
const { $pinia } = nuxtApp
nuxtApp.provide('featureFlag', (key, defaultValue = false) => {
return featureFlagsStore.getFlag(key, defaultValue)
})
try {
// Pass pinia instance for SSR compatibility
const featureFlagsStore = useFeatureFlagsStore($pinia)
// Fetch flags during SSR to prevent hydration mismatches
if (!featureFlagsStore.isLoaded) {
await featureFlagsStore.fetchFlags()
}
} catch (error) {
console.error('Feature flags plugin failed:', error)
}
})

View File

@ -1,7 +1,11 @@
---
services:
api: &api-environment
image: jhumanj/opnform-api:latest
build:
context: .
dockerfile: docker/Dockerfile.api
args:
APP_VERSION: "local-test-1.0.0"
container_name: opnform-api
volumes: &api-environment-volumes
- opnform_storage:/usr/share/nginx/html/storage:rw
@ -62,7 +66,11 @@ services:
start_period: 70s # Allow time for first scheduled run and cache write
ui:
image: jhumanj/opnform-client:latest
build:
context: .
dockerfile: docker/Dockerfile.client
args:
APP_VERSION: "local-test-1.0.0"
container_name: opnform-client
env_file:
- ./client/.env

View File

@ -27,6 +27,9 @@ RUN composer install --optimize-autoloader --no-interaction \
# Final stage - smaller runtime image
FROM php:8.3-fpm-alpine
# Accept version build argument
ARG APP_VERSION=unknown
# Install runtime dependencies
RUN apk add --no-cache \
libzip \
@ -75,6 +78,9 @@ RUN mkdir -p storage/framework/sessions \
# Copy the entire application from the builder stage
COPY --from=builder /app/ ./
# Set version as environment variable (more reliable than file approach)
ENV APP_VERSION_DOCKER=$APP_VERSION
# Setup entrypoint
COPY docker/php-fpm-entrypoint /usr/local/bin/opnform-entrypoint
RUN chmod a+x /usr/local/bin/*