feat(deploy): publish Discord bot image
This commit is contained in:
@@ -135,6 +135,21 @@ jobs:
|
||||
docker push "git.garvis.dev/dmg/minecraft-account-manager:${VERSION}"
|
||||
docker push git.garvis.dev/dmg/minecraft-account-manager:latest
|
||||
|
||||
- name: Build and push Discord bot image
|
||||
if: steps.release.outputs.created == 'true'
|
||||
env:
|
||||
VERSION: ${{ steps.release.outputs.version }}
|
||||
run: |
|
||||
docker build \
|
||||
--platform linux/amd64 \
|
||||
--target bot \
|
||||
--build-arg VERSION="$VERSION" \
|
||||
-t "git.garvis.dev/dmg/minecraft-account-manager-bot:${VERSION}" \
|
||||
-t git.garvis.dev/dmg/minecraft-account-manager-bot:latest \
|
||||
.
|
||||
docker push "git.garvis.dev/dmg/minecraft-account-manager-bot:${VERSION}"
|
||||
docker push git.garvis.dev/dmg/minecraft-account-manager-bot:latest
|
||||
|
||||
- name: Build and push migration image
|
||||
if: steps.release.outputs.created == 'true'
|
||||
env:
|
||||
|
||||
+14
@@ -34,6 +34,20 @@ USER app
|
||||
EXPOSE 3000
|
||||
CMD ["node", "apps/web/server.js"]
|
||||
|
||||
FROM dependencies AS bot
|
||||
ARG VERSION=development
|
||||
LABEL org.opencontainers.image.title="Minecraft Account Manager Discord Bot" \
|
||||
org.opencontainers.image.version="${VERSION}" \
|
||||
org.opencontainers.image.source="https://git.garvis.dev/dmg/minecraft-account-manager"
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
RUN addgroup --system app && adduser --system --ingroup app app
|
||||
COPY --chown=app:app package.json package-lock.json tsconfig.base.json ./
|
||||
COPY --chown=app:app apps/discord-bot ./apps/discord-bot
|
||||
COPY --chown=app:app packages ./packages
|
||||
USER app
|
||||
CMD ["npm", "run", "start", "--workspace", "@minecraft-account-manager/discord-bot"]
|
||||
|
||||
FROM dependencies AS migrate
|
||||
ARG VERSION=development
|
||||
LABEL org.opencontainers.image.title="Minecraft Account Manager Migrations" \
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { GET } from "./route";
|
||||
|
||||
describe("health endpoint", () => {
|
||||
it("reports process readiness without requiring external services", async () => {
|
||||
const response = GET();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("cache-control")).toBe("no-store");
|
||||
expect(await response.json()).toEqual({ status: "ok" });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
export function GET(): Response {
|
||||
return Response.json(
|
||||
{ status: "ok" },
|
||||
{
|
||||
headers: {
|
||||
"Cache-Control": "no-store",
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
## 2026-08-01
|
||||
|
||||
* **Extend**: Added a releasable Discord bot image and a dependency-free web health endpoint for Kubernetes deployment.
|
||||
* **Verify**: Confirmed the initial `v1.0.0` release, public Velocity JAR, and versioned and `latest` web and migration image manifests.
|
||||
* **Create**: Added Gitea CI and semantic-release pipelines for downloadable Velocity JARs and versioned web and migration images.
|
||||
* **Document**: Added container deployment order, artifact names, and required repository secrets.
|
||||
|
||||
@@ -3,7 +3,7 @@ type: User Story
|
||||
title: Deploy and operate the platform securely
|
||||
description: Operators have repeatable builds, migrations, credential provisioning, configuration, and security checks.
|
||||
tags: [operations, security, database, deployment]
|
||||
timestamp: 2026-08-01T19:01:47Z
|
||||
timestamp: 2026-08-01T19:46:09Z
|
||||
story_id: US-015
|
||||
status: verified
|
||||
---
|
||||
@@ -21,6 +21,7 @@ As a platform operator, I want reproducible deployment and security controls, so
|
||||
- [x] The Velocity Gradle wrapper produces a tested shaded JAR.
|
||||
- [x] Environment examples document database, Keycloak, Discord, trusted proxy, and ProxyCheck settings without secrets.
|
||||
- [x] The web application sets CSP, framing, MIME, referrer, and permissions headers.
|
||||
- [x] The web runtime provides a dependency-free health endpoint for orchestration probes.
|
||||
- [x] npm dependency audit and Semgrep security review complete without findings at the last verified change.
|
||||
- [x] Architecture, Keycloak, API error, security, bot, and Velocity operating documentation is available.
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ type: User Story
|
||||
title: Build and publish versioned releases
|
||||
description: Gitea Actions validate every change and publish semantically versioned Velocity and container artifacts.
|
||||
tags: [operations, ci, release, velocity, docker]
|
||||
timestamp: 2026-08-01T19:18:42Z
|
||||
timestamp: 2026-08-01T19:46:09Z
|
||||
story_id: US-016
|
||||
status: verified
|
||||
status: implemented
|
||||
---
|
||||
|
||||
# User Story
|
||||
@@ -21,6 +21,7 @@ As a platform operator, I want automated validation and semantic releases, so th
|
||||
- [x] A release build embeds the semantic version in the Velocity plugin and JAR filename.
|
||||
- [x] A public Gitea release exposes the versioned Velocity JAR as a downloadable asset.
|
||||
- [x] Releases publish versioned and `latest` web runtime images to the Gitea registry.
|
||||
- [ ] Releases publish versioned and `latest` Discord bot images to the Gitea registry.
|
||||
- [x] Releases publish versioned and `latest` migration images that run versioned Drizzle migrations.
|
||||
- [x] Runtime containers use unprivileged users and exclude development source and secrets where practical.
|
||||
- [x] Operators are told which repository secrets must be configured before the first push.
|
||||
@@ -36,7 +37,7 @@ As a platform operator, I want automated validation and semantic releases, so th
|
||||
|
||||
# Validation
|
||||
|
||||
Local OKF, lint, typecheck, test, Next.js build, and versioned Velocity JAR checks pass. Initial Gitea CI and release runs succeeded. Release `v1.0.0` provides a publicly downloadable JAR whose Velocity metadata reports `1.0.0`. Registry manifests were resolved for versioned and `latest` web and migration images. Pull-request commitlint configuration is present; its conditional execution will be exercised by the first pull request.
|
||||
Local OKF, lint, typecheck, test, Next.js build, and versioned Velocity JAR checks pass. Initial Gitea CI and release runs succeeded. Release `v1.0.0` provides a publicly downloadable JAR whose Velocity metadata reports `1.0.0`. Registry manifests were resolved for versioned and `latest` web and migration images. Discord bot image publication is implemented for the next feature release. Pull-request commitlint configuration is present; its conditional execution will be exercised by the first pull request.
|
||||
|
||||
# Related Stories
|
||||
|
||||
|
||||
@@ -33,11 +33,17 @@ Each release creates:
|
||||
- Gitea release asset `minecraft-account-manager-velocity-VERSION.jar`
|
||||
- `git.garvis.dev/dmg/minecraft-account-manager:VERSION`
|
||||
- `git.garvis.dev/dmg/minecraft-account-manager:latest`
|
||||
- `git.garvis.dev/dmg/minecraft-account-manager-bot:VERSION`
|
||||
- `git.garvis.dev/dmg/minecraft-account-manager-bot:latest`
|
||||
- `git.garvis.dev/dmg/minecraft-account-manager-migrate:VERSION`
|
||||
- `git.garvis.dev/dmg/minecraft-account-manager-migrate:latest`
|
||||
|
||||
Use immutable version tags for deployments. `latest` is a convenience pointer to the newest release.
|
||||
|
||||
## Discord bot
|
||||
|
||||
Run exactly one bot replica with the same immutable release version as the web application. It requires `DATABASE_URL`, `APP_URL`, `DISCORD_BOT_TOKEN`, and `DISCORD_GUILD_ID`. Deploy slash commands separately with the release image when command definitions change.
|
||||
|
||||
## Database migration
|
||||
|
||||
Run the migration image for the same version before starting or replacing the web container:
|
||||
|
||||
Reference in New Issue
Block a user