You've already forked AstralRinth
forked from didirus/AstralRinth
build: deploy on both environments (#5129)
* build: deploy on both environments * build: missing whitespace * build: add path filter * build: add sentry env * build: inherit secrets * remove if check * Revert "remove if check" This reverts commit b2ffe1d611269ddaf13bdbfacfdb89cd40316c29. * remove if check 2 * Fix Wrangler env * Fix Wrangler env but for real this time * Alternative method of getting URLs * Check for environment instead * Fix comment * Clickable commit * Set PREVIEW build var * Fix commit shown in comment * Fix linting errors * ) * add preview banner * prepr * prepr again * .. --------- Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
60
.github/workflows/frontend-deploy.yml
vendored
60
.github/workflows/frontend-deploy.yml
vendored
@@ -13,12 +13,16 @@ on:
|
||||
- '**/wrangler.jsonc'
|
||||
- '**/pnpm-*.yaml'
|
||||
- '.github/workflows/frontend-deploy.yml'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs:
|
||||
environment:
|
||||
required: true
|
||||
type: string
|
||||
description: 'The environment to deploy to (staging-preview or production-preview)'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.repository_owner == 'modrinth'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -34,15 +38,28 @@ jobs:
|
||||
id: meta
|
||||
run: |
|
||||
echo "cmd=deploy" >> $GITHUB_OUTPUT
|
||||
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
|
||||
|
||||
ENV_INPUT="${{ inputs.environment }}"
|
||||
REF="${{ github.ref }}"
|
||||
SHA_SHORT="${GITHUB_SHA::8}"
|
||||
|
||||
if [ "$ENV_INPUT" = "staging-preview" ]; then
|
||||
echo "env=staging" >> $GITHUB_OUTPUT
|
||||
echo "url=https://git-$SHA_SHORT-frontend-staging.modrinth.workers.dev" >> $GITHUB_OUTPUT
|
||||
echo "cmd=versions upload --preview-alias git-$SHA_SHORT --var PREVIEW:true" >> $GITHUB_OUTPUT
|
||||
|
||||
elif [ "$ENV_INPUT" = "production-preview" ]; then
|
||||
echo "env=production" >> $GITHUB_OUTPUT
|
||||
echo "url=https://git-$SHA_SHORT-frontend.modrinth.workers.dev" >> $GITHUB_OUTPUT
|
||||
echo "cmd=versions upload --preview-alias git-$SHA_SHORT --var PREVIEW:true" >> $GITHUB_OUTPUT
|
||||
|
||||
elif [ "$REF" = "refs/heads/main" ]; then
|
||||
echo "env=staging" >> $GITHUB_OUTPUT
|
||||
echo "url=https://staging.modrinth.com" >> $GITHUB_OUTPUT
|
||||
elif [ "${{ github.ref }}" != "refs/heads/prod" ] && [ "${{ github.ref }}" != "refs/heads/main" ]; then
|
||||
echo "env=staging" >> $GITHUB_OUTPUT
|
||||
echo "url=https://git-${GITHUB_SHA::8}-frontend-staging.modrinth.workers.dev" >> $GITHUB_OUTPUT
|
||||
echo "cmd=versions upload --preview-alias git-${GITHUB_SHA::8} --var PREVIEW:true" >> $GITHUB_OUTPUT
|
||||
|
||||
else
|
||||
# Production env should be empty
|
||||
# Production env (no preview)
|
||||
echo "env=production" >> $GITHUB_OUTPUT
|
||||
echo "url=https://modrinth.com" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
@@ -77,6 +94,8 @@ jobs:
|
||||
CF_PAGES_BRANCH: ${{ github.ref_name }}
|
||||
CF_PAGES_COMMIT_SHA: ${{ github.sha }}
|
||||
CF_PAGES_URL: ${{ steps.meta.outputs.url }}
|
||||
BUILD_ENV: ${{ steps.meta.outputs.env }}
|
||||
PREVIEW: ${{ inputs.environment != '' && 'true' || 'false' }}
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
|
||||
- name: Create Sentry release and upload sourcemaps
|
||||
@@ -86,7 +105,7 @@ jobs:
|
||||
SENTRY_ORG: modrinth
|
||||
SENTRY_PROJECT: knossos-server
|
||||
with:
|
||||
environment: ${{ steps.meta.outputs.env || 'production' }}
|
||||
environment: ${{ steps.meta.outputs.env }}
|
||||
sourcemaps: ./apps/frontend/.output/server
|
||||
url_prefix: '~/'
|
||||
|
||||
@@ -96,7 +115,7 @@ jobs:
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
environment: ${{ steps.meta.outputs.env }}
|
||||
environment: ${{ steps.meta.outputs.env != 'production' && steps.meta.outputs.env || '' }}
|
||||
workingDirectory: ./apps/frontend
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
@@ -111,15 +130,14 @@ jobs:
|
||||
--data '{"hosts": ["modrinth.com", "www.modrinth.com", "staging.modrinth.com"]}' \
|
||||
https://api.cloudflare.com/client/v4/zones/e39df17b9c4ef44cbce2646346ee6d33/purge_cache
|
||||
|
||||
- name: Comment deploy URL on PR
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: peter-evans/create-or-update-comment@v4
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
## 🚀 Frontend Deploy
|
||||
- name: Write deployment URL to file
|
||||
if: ${{ inputs.environment != '' }}
|
||||
run: |
|
||||
echo "${{ steps.meta.outputs.url }}" > deployment-url-${{ inputs.environment }}.txt
|
||||
|
||||
| Commit | URL |
|
||||
|--------|-----|
|
||||
| ${{ github.event.pull_request.head.sha }} | ${{ steps.wrangler.outputs.deployment-url }} |
|
||||
comment-tag: frontend-deploy
|
||||
- name: Upload deployment URL
|
||||
if: ${{ inputs.environment != '' }}
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: deployment-url-${{ inputs.environment }}
|
||||
path: deployment-url-${{ inputs.environment }}.txt
|
||||
|
||||
72
.github/workflows/frontend-preview.yml
vendored
Normal file
72
.github/workflows/frontend-preview.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Deploy frontend preview
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'apps/frontend/**/*'
|
||||
- 'packages/ui/**/*'
|
||||
- 'packages/utils/**/*'
|
||||
- 'packages/assets/**/*'
|
||||
- '**/wrangler.jsonc'
|
||||
- '**/pnpm-*.yaml'
|
||||
- '.github/workflows/frontend-preview.yml'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: ./.github/workflows/frontend-deploy.yml
|
||||
secrets: inherit
|
||||
strategy:
|
||||
matrix:
|
||||
environment: [staging-preview, production-preview]
|
||||
with:
|
||||
environment: ${{ matrix.environment }}
|
||||
|
||||
comment:
|
||||
if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy
|
||||
steps:
|
||||
- name: Download deployment URLs
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: deployment-url-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Read deployment URLs
|
||||
id: urls
|
||||
run: |
|
||||
STAGING_PREVIEW_URL=$(cat deployment-url-staging-preview.txt)
|
||||
PRODUCTION_PREVIEW_URL=$(cat deployment-url-production-preview.txt)
|
||||
|
||||
echo "Production preview URL: $PRODUCTION_PREVIEW_URL"
|
||||
echo "Staging preview URL: $STAGING_PREVIEW_URL"
|
||||
|
||||
echo "staging-preview-url=$STAGING_PREVIEW_URL" >> $GITHUB_OUTPUT
|
||||
echo "production-preview-url=$PRODUCTION_PREVIEW_URL" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Find comment
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: peter-evans/find-comment@v3
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
comment-author: 'github-actions[bot]'
|
||||
body-includes: Frontend previews
|
||||
|
||||
- name: Comment deploy URL on PR
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: peter-evans/create-or-update-comment@v5
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
body: |
|
||||
## Frontend previews
|
||||
|
||||
Last deployed commit is [${{ github.sha }}](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.sha }})
|
||||
|
||||
| Environment | URL |
|
||||
|-------------|-----|
|
||||
| staging | ${{ steps.urls.outputs.staging-preview-url }} |
|
||||
| production | ${{ steps.urls.outputs.production-preview-url }} |
|
||||
edit-mode: replace
|
||||
@@ -187,6 +187,8 @@ export default defineNuxtConfig({
|
||||
pyroBaseUrl: process.env.PYRO_BASE_URL,
|
||||
siteUrl: getDomain(),
|
||||
production: isProduction(),
|
||||
buildEnv: process.env.BUILD_ENV,
|
||||
preview: process.env.PREVIEW === 'true',
|
||||
featureFlagOverrides: getFeatureFlagOverrides(),
|
||||
|
||||
owner: process.env.VERCEL_GIT_REPO_OWNER || 'modrinth',
|
||||
@@ -253,6 +255,7 @@ export default defineNuxtConfig({
|
||||
},
|
||||
replace: {
|
||||
__SENTRY_RELEASE__: JSON.stringify(process.env.CF_PAGES_COMMIT_SHA || 'unknown'),
|
||||
__SENTRY_ENVIRONMENT__: JSON.stringify(process.env.BUILD_ENV || 'development'),
|
||||
},
|
||||
},
|
||||
devtools: {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { BlueskyIcon, DiscordIcon, GithubIcon, MastodonIcon, TwitterIcon } from '@modrinth/assets'
|
||||
import {
|
||||
AutoLink,
|
||||
ButtonStyled,
|
||||
defineMessage,
|
||||
defineMessages,
|
||||
@@ -15,6 +16,7 @@ import TextLogo from '~/components/brand/TextLogo.vue'
|
||||
const flags = useFeatureFlags()
|
||||
const { formatMessage } = useVIntl()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const messages = defineMessages({
|
||||
modrinthInformation: {
|
||||
@@ -302,6 +304,27 @@ function developerModeIncrement() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="flags.developerMode" class="m-0 text-sm text-secondary">
|
||||
Based on
|
||||
<a
|
||||
v-if="config.public.owner && config.public.branch"
|
||||
class="hover:underline"
|
||||
target="_blank"
|
||||
:href="`https://github.com/${config.public.owner}/code/tree/${config.public.branch}`"
|
||||
>
|
||||
{{ config.public.owner }}/{{ config.public.branch }}
|
||||
</a>
|
||||
@
|
||||
<span v-if="config.public.hash === 'unknown'">unknown</span>
|
||||
<AutoLink
|
||||
v-else
|
||||
class="text-link"
|
||||
target="_blank"
|
||||
:to="`https://github.com/${config.public.owner}/code/commit/${config.public.hash}`"
|
||||
>
|
||||
{{ config.public.hash }}
|
||||
</AutoLink>
|
||||
</p>
|
||||
<div class="flex justify-center text-center text-xs font-medium text-secondary opacity-50">
|
||||
{{ formatMessage(messages.legalDisclaimer) }}
|
||||
</div>
|
||||
|
||||
86
apps/frontend/src/components/ui/banner/PreviewBanner.vue
Normal file
86
apps/frontend/src/components/ui/banner/PreviewBanner.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import { XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
IntlFormatted,
|
||||
normalizeChildren,
|
||||
PagewideBanner,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const flags = useFeatureFlags()
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const messages = defineMessages({
|
||||
title: {
|
||||
id: 'layout.banner.preview.title',
|
||||
defaultMessage: `This is a preview deploy of the Modrinth website.`,
|
||||
},
|
||||
description: {
|
||||
id: 'layout.banner.preview.description',
|
||||
defaultMessage: `If you meant to access the official Modrinth website, visit <link>https://modrinth.com</link>. This preview deploy is used by Modrinth staff for testing purposes. It was built using <branch-link>{owner}/{branch}</branch-link> @ {commit}.`,
|
||||
},
|
||||
})
|
||||
|
||||
function hidePreviewBanner() {
|
||||
flags.value.hidePreviewBanner = true
|
||||
saveFeatureFlags()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PagewideBanner v-if="!flags.hidePreviewBanner" variant="info">
|
||||
<template #title>
|
||||
<span>{{ formatMessage(messages.title) }}</span>
|
||||
</template>
|
||||
<template #description>
|
||||
<span>
|
||||
<IntlFormatted
|
||||
:message-id="messages.description"
|
||||
:values="{
|
||||
owner: config.public.owner,
|
||||
branch: config.public.branch,
|
||||
}"
|
||||
>
|
||||
<template #link="{ children }">
|
||||
<a href="https://modrinth.com" target="_blank" rel="noopener" class="text-link">
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</a>
|
||||
</template>
|
||||
<template #branch-link="{ children }">
|
||||
<a
|
||||
:href="`https://github.com/${config.public.owner}/code/tree/${config.public.branch}`"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="hover:underline"
|
||||
>
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</a>
|
||||
</template>
|
||||
<template #commit>
|
||||
<span v-if="config.public.hash === 'unknown'">unknown</span>
|
||||
<a
|
||||
v-else
|
||||
:href="`https://github.com/${config.public.owner}/code/commit/${config.public.hash}`"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="text-link"
|
||||
>
|
||||
{{ config.public.hash }}
|
||||
</a>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</span>
|
||||
</template>
|
||||
<template #actions_right>
|
||||
<ButtonStyled type="transparent" circular>
|
||||
<button :aria-label="formatMessage(commonMessages.closeButton)" @click="hidePreviewBanner">
|
||||
<XIcon aria-hidden="true" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</PagewideBanner>
|
||||
</template>
|
||||
@@ -42,22 +42,7 @@ export const DEFAULT_FEATURE_FLAGS = validateValues({
|
||||
hideRussiaCensorshipBanner: false,
|
||||
serverDiscovery: false,
|
||||
disablePrettyProjectUrlRedirects: false,
|
||||
// advancedRendering: true,
|
||||
// externalLinksNewTab: true,
|
||||
// notUsingBlockers: false,
|
||||
// hideModrinthAppPromos: false,
|
||||
// preferredDarkTheme: 'dark',
|
||||
// hideStagingBanner: false,
|
||||
|
||||
// Project display modes
|
||||
// modSearchDisplayMode: 'list',
|
||||
// pluginSearchDisplayMode: 'list',
|
||||
// resourcePackSearchDisplayMode: 'gallery',
|
||||
// modpackSearchDisplayMode: 'list',
|
||||
// shaderSearchDisplayMode: 'gallery',
|
||||
// dataPackSearchDisplayMode: 'list',
|
||||
// userProjectDisplayMode: 'list',
|
||||
// collectionProjectDisplayMode: 'list',
|
||||
hidePreviewBanner: false,
|
||||
} as const)
|
||||
|
||||
export type FeatureFlag = keyof typeof DEFAULT_FEATURE_FLAGS
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
route.path !== '/settings/billing'
|
||||
"
|
||||
/>
|
||||
<PreviewBanner v-if="config.public.buildEnv === 'production' && config.public.preview" />
|
||||
<StagingBanner v-if="config.public.apiBaseUrl.startsWith('https://staging-api.modrinth.com')" />
|
||||
<GeneratedStateErrorsBanner
|
||||
:errors="generatedStateErrors"
|
||||
@@ -723,6 +724,7 @@ import { isAdmin, isStaff, UserBadge } from '@modrinth/utils'
|
||||
import TextLogo from '~/components/brand/TextLogo.vue'
|
||||
import BatchCreditModal from '~/components/ui/admin/BatchCreditModal.vue'
|
||||
import GeneratedStateErrorsBanner from '~/components/ui/banner/GeneratedStateErrorsBanner.vue'
|
||||
import PreviewBanner from '~/components/ui/banner/PreviewBanner.vue'
|
||||
import RussiaBanner from '~/components/ui/banner/RussiaBanner.vue'
|
||||
import StagingBanner from '~/components/ui/banner/StagingBanner.vue'
|
||||
import SubscriptionPaymentFailedBanner from '~/components/ui/banner/SubscriptionPaymentFailedBanner.vue'
|
||||
|
||||
@@ -1337,6 +1337,12 @@
|
||||
"layout.banner.build-fail.title": {
|
||||
"message": "Error generating state from API when building."
|
||||
},
|
||||
"layout.banner.preview.description": {
|
||||
"message": "If you meant to access the official Modrinth website, visit <link>https://modrinth.com</link>. This preview deploy is used by Modrinth staff for testing purposes. It was built using <branch-link>{owner}/{branch}</branch-link> @ {commit}."
|
||||
},
|
||||
"layout.banner.preview.title": {
|
||||
"message": "This is a preview deploy of the Modrinth website."
|
||||
},
|
||||
"layout.banner.staging.description": {
|
||||
"message": "The staging environment is completely separate from the production Modrinth database. This is used for testing and debugging purposes, and may be running in-development versions of the Modrinth backend or frontend newer than the production instance."
|
||||
},
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { sentryCloudflareNitroPlugin } from '@sentry/nuxt/module/plugins'
|
||||
|
||||
declare const __SENTRY_RELEASE__: string
|
||||
declare const __SENTRY_ENVIRONMENT__: string
|
||||
|
||||
export default defineNitroPlugin(
|
||||
sentryCloudflareNitroPlugin({
|
||||
dsn: 'https://9cf8f56ab7055ab6b1042fad535f2a44@o485889.ingest.us.sentry.io/4510709722185728',
|
||||
tracesSampleRate: 0.0001, // match with wrangler.jsonc
|
||||
release: __SENTRY_RELEASE__,
|
||||
environment: __SENTRY_ENVIRONMENT__,
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<router-link v-if="to.path || to.query || to.startsWith('/')" :to="to" v-bind="$attrs">
|
||||
<router-link v-if="to?.path || to?.query || to?.startsWith('/')" :to="to" v-bind="$attrs">
|
||||
<slot />
|
||||
</router-link>
|
||||
<a v-else-if="to.startsWith('http')" :href="to" v-bind="$attrs">
|
||||
<a v-else-if="to?.startsWith('http')" :href="to" v-bind="$attrs">
|
||||
<slot />
|
||||
</a>
|
||||
<span v-else v-bind="$attrs">
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"NODE_ENV",
|
||||
"SITE_URL",
|
||||
"BASE_URL",
|
||||
"PREVIEW",
|
||||
"BUILD_ENV",
|
||||
"FLAG_OVERRIDES",
|
||||
"BROWSER_BASE_URL",
|
||||
"RATE_LIMIT_IGNORE_KEY",
|
||||
@@ -32,7 +34,9 @@
|
||||
"RUST_*",
|
||||
"RUSTFLAGS",
|
||||
"FORCE_COLOR",
|
||||
"NEXTEST_*"
|
||||
"NEXTEST_*",
|
||||
"BUILD_ENV",
|
||||
"PREVIEW"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
|
||||
Reference in New Issue
Block a user