refactor: trim v2 hardening scaffolding

This commit is contained in:
ajnart committed 2026-07-30 15:19:17 +02:00
1 parent ecfb9d59e0
commit 2eb0baf17e
75 files changed
+334 -2067

No files matched your search

+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_APPROVE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
client-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
permission-pull-requests: write # required to approve pull request
- name: Install GitHub CLI
+31 -193
View File
@@ -47,24 +47,6 @@ env:
PREVIEW_IMAGE: ghcr.io/homarr-labs/homarr-test
jobs:
formatting:
name: Formatting
if: github.event_name != 'pull_request_target' && (github.event_name != 'workflow_dispatch' || inputs.operation != 'cleanup')
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
if: "!env.ACT"
with:
persist-credentials: false
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
- name: Setup
uses: ./tooling/github/setup
- name: Check formatting
run: pnpm format
fast-gate:
name: Fast gate
if: github.event_name != 'pull_request_target' && (github.event_name != 'workflow_dispatch' || inputs.operation != 'cleanup')
@@ -107,9 +89,6 @@ jobs:
- name: Validate workspace configuration
run: pnpm lint:ws
- name: Validate GitHub Actions
run: pnpm check:actions
- name: Validate Custom Widget architecture
run: pnpm check:custom-widgets
@@ -121,63 +100,12 @@ jobs:
pnpm --filter nextjs build
pnpm check:custom-widget-bundle
unit:
name: Full unit suite
if: github.event_name != 'pull_request_target' && (github.event_name != 'workflow_dispatch' || inputs.operation != 'cleanup')
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
if: "!env.ACT"
with:
persist-credentials: false
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
- name: Setup
uses: ./tooling/github/setup
- name: Copy environment defaults
run: cp .env.example .env
- name: Run unit tests
run: pnpm test
migration-matrix:
name: Database migrations (${{ matrix.database }})
if: github.event_name != 'pull_request_target' && (github.event_name != 'workflow_dispatch' || inputs.operation != 'cleanup')
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- database: SQLite
test_file: packages/db/test/sqlite-migration.spec.ts
- database: MySQL
test_file: packages/db/test/mysql-migration.spec.ts
- database: PostgreSQL
test_file: packages/db/test/postgresql-migration.spec.ts
steps:
- uses: actions/checkout@v7
if: "!env.ACT"
with:
persist-credentials: false
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
- name: Setup
uses: ./tooling/github/setup
- name: Copy environment defaults
run: cp .env.example .env
- name: Run ${{ matrix.database }} migration tests
env:
MIGRATION_TEST_FILE: ${{ matrix.test_file }}
run: pnpm exec vitest run --project db-node "$MIGRATION_TEST_FILE"
container:
name: Container and E2E
needs: [formatting, fast-gate, unit, migration-matrix]
needs: fast-gate
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && github.event.pull_request.draft == false) ||
@@ -310,12 +238,11 @@ jobs:
run: echo "Act validated the publication path; external GHCR writes are disabled locally."
preview-arm64:
name: Arm64 image
needs: [formatting, fast-gate, unit, migration-matrix]
name: Build arm64 preview image
needs: fast-gate
if: |
(
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && github.event.pull_request.draft == false) ||
(github.event_name == 'pull_request' && github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
runs-on: ubuntu-24.04-arm
@@ -333,12 +260,7 @@ jobs:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
- name: Log in to GHCR
if: |
!env.ACT &&
(
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
if: "!env.ACT"
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
@@ -351,12 +273,7 @@ jobs:
- name: Build and push arm64 preview image by digest
id: preview-build
if: |
!env.ACT &&
(
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
if: "!env.ACT"
uses: docker/build-push-action@v7
with:
context: .
@@ -371,34 +288,12 @@ jobs:
TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY=${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
- name: Build arm64 image without publication
if: |
!env.ACT &&
(
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)
)
uses: docker/build-push-action@v7
with:
context: .
network: host
platforms: linux/arm64
outputs: type=cacheonly
cache-from: type=gha,scope=homarr-linux-arm64
cache-to: type=gha,scope=homarr-linux-arm64,mode=max
secrets: |
TURBO_API=${{ secrets.TURBO_API }}
TURBO_TEAM=${{ secrets.TURBO_TEAM }}
TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY=${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
publish-preview:
name: Publish multi-platform preview image
needs: [container, preview-arm64]
if: |
(
github.event_name == 'merge_group' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
runs-on: ubuntu-latest
@@ -411,12 +306,7 @@ jobs:
PREVIEW_TAG: pr-${{ github.event.pull_request.number || inputs.pr_number }}
steps:
- name: Log in to GHCR
if: |
!env.ACT &&
(
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
if: "!env.ACT"
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
@@ -424,17 +314,11 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
if: |
!env.ACT &&
(
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
if: "!env.ACT"
uses: docker/setup-buildx-action@v4
- name: Verify PR head before publication
id: publication-preflight
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
env:
EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
@@ -446,28 +330,15 @@ jobs:
pull_number: context.payload.pull_request.number,
});
if (pull.state !== "open") {
core.notice(`PR #${pull.number} is ${pull.state}; preview publication is no longer needed.`);
core.setOutput("publish", "false");
core.setFailed(`PR #${pull.number} is ${pull.state}; refusing to publish its preview.`);
return;
}
if (pull.head.sha !== process.env.EXPECTED_HEAD_SHA) {
core.notice(`PR #${pull.number} moved to ${pull.head.sha}; a newer run owns preview publication.`);
core.setOutput("publish", "false");
return;
core.setFailed(`PR #${pull.number} moved from ${process.env.EXPECTED_HEAD_SHA} to ${pull.head.sha}.`);
}
core.setOutput("publish", "true");
- name: Publish preview manifest
if: |
!env.ACT &&
(
(
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository &&
steps.publication-preflight.outputs.publish == 'true'
) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
if: "!env.ACT"
env:
AMD64_DIGEST: ${{ needs.container.outputs.digest }}
ARM64_DIGEST: ${{ needs.preview-arm64.outputs.digest }}
@@ -477,16 +348,7 @@ jobs:
"${PREVIEW_IMAGE}@${ARM64_DIGEST}"
- name: Verify preview manifest platforms
if: |
!env.ACT &&
(
(
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository &&
steps.publication-preflight.outputs.publish == 'true'
) ||
(github.event_name == 'workflow_dispatch' && inputs.operation == 'publish')
)
if: "!env.ACT"
run: |
image="${PREVIEW_IMAGE}:${PREVIEW_TAG}"
manifest="$(docker buildx imagetools inspect "$image" --raw)"
@@ -497,12 +359,6 @@ jobs:
done
docker buildx imagetools inspect "$image"
- name: Confirm multi-platform preview validation
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)
run: echo "Both platform image builds completed; registry publication is intentionally disabled for this event."
cleanup:
name: Clean up preview image
if: github.event_name == 'pull_request_target' || (github.event_name == 'workflow_dispatch' && inputs.operation == 'cleanup')
@@ -527,42 +383,24 @@ jobs:
const packageName = "homarr-test";
const org = context.repo.owner;
const tag = process.env.IMAGE_TAG;
const attempts = context.eventName === "pull_request_target" ? 7 : 1;
for (let attempt = 1; attempt <= attempts; attempt += 1) {
let versions;
try {
versions = await github.paginate(
github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg,
{ package_type: "container", package_name: packageName, org, per_page: 100 },
);
} catch (error) {
if (error.status === 404) {
core.info(`Package "${packageName}" does not exist; cleanup is already complete.`);
return;
}
throw error;
}
const targets = versions.filter((version) =>
version.metadata?.container?.tags?.includes(tag),
);
if (targets.length > 0) {
for (const target of targets) {
await github.rest.packages.deletePackageVersionForOrg({
package_type: "container",
package_name: packageName,
org,
package_version_id: target.id,
});
core.info(`Deleted package version ${target.id} (${tag})`);
}
return;
}
if (attempt < attempts) {
core.info(`No "${tag}" version found yet; retrying cleanup after publication settles.`);
await new Promise((resolve) => setTimeout(resolve, 5_000));
}
const versions = await github.paginate(
github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg,
{ package_type: "container", package_name: packageName, org, per_page: 100 },
);
const target = versions.find((version) =>
version.metadata?.container?.tags?.includes(tag),
);
if (!target) {
core.info(`No package version found with tag "${tag}"`);
return;
}
core.info(`No package version found with tag "${tag}"; cleanup is already complete.`);
await github.rest.packages.deletePackageVersionForOrg({
package_type: "container",
package_name: packageName,
org,
package_version_id: target.id,
});
core.info(`Deleted package version ${target.id} (${tag})`);
- name: Show Act cleanup result
if: env.ACT
@@ -22,7 +22,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.CROWDIN_APP_PRIVATE_KEY }}
app-id: ${{ secrets.CROWDIN_APP_ID }}
client-id: ${{ secrets.CROWDIN_APP_ID }}
permission-contents: write # required to commit to crowdin branch
permission-pull-requests: write # required to create pull request
@@ -52,7 +52,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_APPROVE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
client-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
permission-pull-requests: write
- name: Approve PR
env:
@@ -64,7 +64,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
client-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
permission-contents: write # write to beta branch (due to merge)
permission-pull-requests: write # merge pull request
- id: automerge
@@ -54,7 +54,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
client-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
permission-contents: write # required to commit package.json & changelog changes, merge them to dev / next and publish the release
- uses: actions/checkout@v7
@@ -246,7 +246,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
client-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
permission-contents: write # required to publish the release
- name: Log in to the Container registry
+30 -110
View File
@@ -1,136 +1,56 @@
name: "[Publish] Documentation and Workshop"
name: "[Deployment] Documentation"
on:
push:
branches: ["v2"]
branches: ["dev"]
paths:
- "apps/docs/**"
- "apps/workshop/**"
- "packages/custom-widgets/**"
- "packages/workshop/**"
- "packages/definitions/**"
- "tooling/typescript/**"
- "patches/**"
- "package.json"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- "turbo.json"
- ".dockerignore"
- "packages/definitions/src/docs/**"
- ".github/workflows/deployment-docs.yml"
workflow_dispatch:
permissions:
contents: read
packages: write
pages: write
id-token: write
concurrency:
group: workshop-image-${{ github.ref }}
cancel-in-progress: true
group: "pages"
cancel-in-progress: false
env:
REGISTRY: ghcr.io
IMAGE_NAME: ghcr.io/homarr-labs/homarr-workshop
SKIP_ENV_VALIDATION: true
TURBO_API: ${{ secrets.TURBO_API }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
jobs:
publish:
name: Publish immutable multi-platform image
build:
runs-on: ubuntu-latest
timeout-minutes: 45
outputs:
digest: ${{ steps.build.outputs.digest }}
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and publish by immutable commit tag
id: build
uses: docker/build-push-action@v7
with:
context: .
file: apps/workshop/Dockerfile
target: production
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
provenance: mode=max
sbom: true
cache-from: type=gha,scope=workshop-production
cache-to: type=gha,scope=workshop-production,mode=max
secrets: |
TURBO_API=${{ secrets.TURBO_API }}
TURBO_TEAM=${{ secrets.TURBO_TEAM }}
TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY=${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
- name: Smoke-test the published digest
- name: Setup
uses: ./tooling/github/setup
- name: Build docs
run: pnpm turbo build --filter=@homarr/docs
env:
IMAGE_DIGEST: ${{ steps.build.outputs.digest }}
run: |
manifest="$(docker buildx imagetools inspect "${IMAGE_NAME}@${IMAGE_DIGEST}" --raw)"
for architecture in amd64 arm64; do
jq --exit-status --arg architecture "$architecture" \
'any(.manifests[]; .platform.os == "linux" and .platform.architecture == $architecture)' \
<<<"$manifest" >/dev/null
done
docker run --detach --name workshop-smoke --platform linux/amd64 \
--publish 127.0.0.1:18090:8090 \
--env HOMARR_WEBSITE_URL=http://127.0.0.1:18090 \
--env WORKSHOP_API_URL=http://127.0.0.1:18090 \
--env WORKSHOP_WEB_URL=http://127.0.0.1:18090/workshop \
--env WORKSHOP_PUBLIC_ORIGIN=http://127.0.0.1:18090 \
--env WORKSHOP_REQUIRE_OAUTH=false \
"${IMAGE_NAME}@${IMAGE_DIGEST}"
for attempt in $(seq 1 60); do
if curl --fail --silent http://127.0.0.1:18090/api/health >/dev/null; then
break
fi
if [ "$attempt" -eq 60 ]; then
docker logs workshop-smoke
exit 1
fi
sleep 1
done
curl --fail --silent --show-error http://127.0.0.1:18090/ >/dev/null
curl --location --fail --silent --show-error http://127.0.0.1:18090/workshop >/dev/null
curl --fail --silent --show-error \
'http://127.0.0.1:18090/api/collections/workshop_listings/records?page=1&perPage=1' >/dev/null
curl --fail --silent --show-error http://127.0.0.1:18090/workshop-runtime-config.js \
| grep --fixed-strings 'workshopApiUrl: "http://127.0.0.1:18090"'
CI: "true"
- name: Setup Pages
uses: actions/configure-pages@v6
- name: Upload pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: "apps/docs/build"
- name: Stop smoke container
if: always()
run: docker rm --force workshop-smoke >/dev/null 2>&1 || true
- name: Record immutable promotion input
env:
IMAGE_DIGEST: ${{ steps.build.outputs.digest }}
run: |
{
echo "### Workshop image candidate"
echo
echo "\`${IMAGE_NAME}@${IMAGE_DIGEST}\`"
echo
echo "This workflow publishes but does not deploy. Promote this exact digest only after staging acceptance and rollback rehearsal."
} >>"$GITHUB_STEP_SUMMARY"
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
@@ -55,7 +55,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_APPROVE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
client-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
permission-pull-requests: write
- name: Approve PR
env:
@@ -67,7 +67,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
client-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
permission-contents: write # write to main branch (due to merge)
permission-pull-requests: write # merge pull request
- id: automerge
+10 -4
View File
@@ -1,9 +1,10 @@
name: "[Docs] Algolia Recrawl"
# Automatic recrawls are intentionally disabled until the external homarr.dev
# host can dispatch this workflow after promoting an immutable Workshop image.
# Publishing an image to GHCR does not make its documentation live.
on:
workflow_run:
workflows: ["[Deployment] Documentation"]
types: [completed]
branches: [dev]
workflow_dispatch:
permissions:
@@ -11,6 +12,11 @@ permissions:
jobs:
recrawl:
if: >-
${{
(github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request')
|| github.event_name == 'workflow_dispatch'
}}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
@@ -37,7 +43,7 @@ jobs:
ALGOLIA_CRAWLER_USER_ID: ${{ secrets.ALGOLIA_CRAWLER_USER_ID }}
ALGOLIA_CRAWLER_API_KEY: ${{ secrets.ALGOLIA_CRAWLER_API_KEY }}
- name: Allow the promoted documentation host to settle
- name: Wait for GitHub Pages to serve the new deployment
run: sleep 60
- name: Trigger Algolia DocSearch recrawl
+34 -1
View File
@@ -5,6 +5,39 @@ on:
types: [released]
jobs:
trigger-docs-release:
name: Trigger Documentation Release
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- name: Obtain token
id: obtainToken
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.HOMARR_DOCS_RELEASE_APP_PRIVATE_KEY }}
client-id: ${{ vars.HOMARR_DOCS_RELEASE_APP_ID }}
owner: homarr-labs
repositories: |
documentation
permission-contents: write # required to dispatch repository workflow
- name: Trigger documentation release
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
SOURCE_TAG: ${{ github.event.release.tag_name }}
run: |
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/homarr-labs/documentation/dispatches \
-d @- <<EOF
{
"event_type": "trigger-release",
"client_payload": {
"tag": "${SOURCE_TAG}"
}
}
EOF
update-bug-report-template:
name: Update Bug Report Template
runs-on: ubuntu-latest
@@ -15,7 +48,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
client-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
permission-contents: write # required to commit to branch
permission-pull-requests: write # required to create pr & enable automerge
- name: Checkout code
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
app-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
client-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
permission-contents: write # required to commit to branch
permission-pull-requests: write # required to create pr & enable automerge
@@ -24,7 +24,7 @@ jobs:
uses: actions/create-github-app-token@v3
with:
private-key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
app-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
client-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
permission-contents: write # required to commit to branch
permission-pull-requests: write # required to create pr & enable automerge
- name: Checkout code
+1 -42
View File
@@ -2,7 +2,6 @@ name: Workshop
on:
pull_request:
merge_group:
push:
branches: [dev, v2]
@@ -11,9 +10,8 @@ permissions:
jobs:
validate:
name: Workshop integration
runs-on: ubuntu-24.04
timeout-minutes: 45
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v6
@@ -28,42 +26,3 @@ jobs:
- run: pnpm --filter @homarr/docs typecheck
- run: pnpm test:workshop
- run: docker build --target production -f apps/workshop/Dockerfile .
- name: Build and smoke-test a non-root documentation deployment
run: |
docker build \
--build-arg DOCS_BASE_URL=/docs-site/ \
--tag homarr-workshop:base-path-smoke \
--target production \
--file apps/workshop/Dockerfile \
.
docker run --detach --name workshop-base-path-smoke \
--publish 127.0.0.1:18093:8090 \
--env DOCS_BASE_URL=/docs-site/ \
--env HOMARR_WEBSITE_URL=http://127.0.0.1:18093 \
--env WORKSHOP_API_URL=http://127.0.0.1:18093 \
--env WORKSHOP_WEB_URL=http://127.0.0.1:18093/docs-site/workshop \
--env WORKSHOP_PUBLIC_ORIGIN=http://127.0.0.1:18093 \
--env WORKSHOP_REQUIRE_OAUTH=false \
homarr-workshop:base-path-smoke
for attempt in $(seq 1 60); do
if curl --fail --silent http://127.0.0.1:18093/api/health >/dev/null; then
break
fi
if [ "$attempt" -eq 60 ]; then
docker logs workshop-base-path-smoke
exit 1
fi
sleep 1
done
curl --fail --silent --show-error http://127.0.0.1:18093/docs-site/ \
| grep --fixed-strings '/docs-site/assets/'
curl --location --fail --silent --show-error http://127.0.0.1:18093/docs-site/workshop/ \
| grep --fixed-strings '/docs-site/workshop/'
curl --fail --silent --show-error \
http://127.0.0.1:18093/docs-site/workshop-runtime-config.js \
| grep --fixed-strings 'workshopWebUrl: "http://127.0.0.1:18093/docs-site/workshop"'
curl --fail --silent --show-error \
'http://127.0.0.1:18093/api/collections/workshop_listings/records?page=1&perPage=1' >/dev/null
- name: Stop non-root documentation smoke container
if: always()
run: docker rm --force workshop-base-path-smoke >/dev/null 2>&1 || true