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:${VERSION}"
|
||||||
docker push git.garvis.dev/dmg/minecraft-account-manager:latest
|
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
|
- name: Build and push migration image
|
||||||
if: steps.release.outputs.created == 'true'
|
if: steps.release.outputs.created == 'true'
|
||||||
env:
|
env:
|
||||||
|
|||||||
+14
@@ -34,6 +34,20 @@ USER app
|
|||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD ["node", "apps/web/server.js"]
|
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
|
FROM dependencies AS migrate
|
||||||
ARG VERSION=development
|
ARG VERSION=development
|
||||||
LABEL org.opencontainers.image.title="Minecraft Account Manager Migrations" \
|
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
|
## 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.
|
* **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.
|
* **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.
|
* **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
|
title: Deploy and operate the platform securely
|
||||||
description: Operators have repeatable builds, migrations, credential provisioning, configuration, and security checks.
|
description: Operators have repeatable builds, migrations, credential provisioning, configuration, and security checks.
|
||||||
tags: [operations, security, database, deployment]
|
tags: [operations, security, database, deployment]
|
||||||
timestamp: 2026-08-01T19:01:47Z
|
timestamp: 2026-08-01T19:46:09Z
|
||||||
story_id: US-015
|
story_id: US-015
|
||||||
status: verified
|
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] The Velocity Gradle wrapper produces a tested shaded JAR.
|
||||||
- [x] Environment examples document database, Keycloak, Discord, trusted proxy, and ProxyCheck settings without secrets.
|
- [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 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] 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.
|
- [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
|
title: Build and publish versioned releases
|
||||||
description: Gitea Actions validate every change and publish semantically versioned Velocity and container artifacts.
|
description: Gitea Actions validate every change and publish semantically versioned Velocity and container artifacts.
|
||||||
tags: [operations, ci, release, velocity, docker]
|
tags: [operations, ci, release, velocity, docker]
|
||||||
timestamp: 2026-08-01T19:18:42Z
|
timestamp: 2026-08-01T19:46:09Z
|
||||||
story_id: US-016
|
story_id: US-016
|
||||||
status: verified
|
status: implemented
|
||||||
---
|
---
|
||||||
|
|
||||||
# User Story
|
# 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 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] 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.
|
- [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] 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] 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.
|
- [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
|
# 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
|
# Related Stories
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,17 @@ Each release creates:
|
|||||||
- Gitea release asset `minecraft-account-manager-velocity-VERSION.jar`
|
- Gitea release asset `minecraft-account-manager-velocity-VERSION.jar`
|
||||||
- `git.garvis.dev/dmg/minecraft-account-manager:VERSION`
|
- `git.garvis.dev/dmg/minecraft-account-manager:VERSION`
|
||||||
- `git.garvis.dev/dmg/minecraft-account-manager:latest`
|
- `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:VERSION`
|
||||||
- `git.garvis.dev/dmg/minecraft-account-manager-migrate:latest`
|
- `git.garvis.dev/dmg/minecraft-account-manager-migrate:latest`
|
||||||
|
|
||||||
Use immutable version tags for deployments. `latest` is a convenience pointer to the newest release.
|
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
|
## Database migration
|
||||||
|
|
||||||
Run the migration image for the same version before starting or replacing the web container:
|
Run the migration image for the same version before starting or replacing the web container:
|
||||||
|
|||||||
Reference in New Issue
Block a user