Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ build/
# uv virtualenv, at the repository root because pyproject.toml is there
.venv/
__pycache__/
result
11 changes: 10 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
FROM golang:1.26-alpine3.24 AS build

# VERSION and COMMIT are baked into the binary at build time via the -ldflags
# below. Defaults mirror flake.nix and CI. The .git directory is excluded from
# the build context, so the real commit has to be supplied by the host, e.g.:
# docker build --build-arg COMMIT=$(git rev-parse HEAD) .
ARG VERSION=0.0.1-alpha
ARG COMMIT=dev

WORKDIR /app

ENV CGO_ENABLED=0
Expand All @@ -11,7 +18,9 @@ COPY . .

RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
go build -trimpath -ldflags="-s -w" -o /output/pen-bot ./cmd/pen-fun
go build -trimpath \
-ldflags="-s -w -X github.com/Neon-Genesis-Linux/pen-bot/internal/core.Version=${VERSION} -X github.com/Neon-Genesis-Linux/pen-bot/internal/core.Commit=${COMMIT}" \
-o /output/pen-bot ./cmd/pen-fun

# The database lives on a volume mounted here. The directory is created in
# this stage so that it can be given to the unprivileged user the runtime
Expand Down
9 changes: 8 additions & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
services:
app:
build: .
build:
context: .
# VERSION and COMMIT are baked into the binary via -ldflags in the
# Dockerfile. Defaults match flake.nix/CI; override from the host, e.g.:
# COMMIT=$(git rev-parse HEAD) docker compose build
args:
VERSION: ${VERSION:-0.0.1-alpha}
COMMIT: ${COMMIT:-dev}
pull_policy: build
env_file:
- .env
Expand Down
67 changes: 62 additions & 5 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,58 @@
nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
};

outputs = {nixpkgs, ...}: let
outputs = inputs: let
nixpkgs = inputs.nixpkgs;
lib = nixpkgs.lib;
systems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin"];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
version = "0.0.1-alpha";
commit =
if (builtins.hasAttr "self" inputs) && inputs.self != null
&& (builtins.hasAttr "rev" inputs.self)
then inputs.self.rev
else "dev";
# Vendored dependency-tree hash. Obtained via vendorHash = lib.fakeHash;
# then reading the reported value and confirming a full `nix build`.
vendorHash = "sha256-QMHsT94FBrbhFOmfHdu8+EmqG+eMLlYZHGKLxuW9Fmk=";

# Only ship first-party Go code and its module files to the build. The
# gitignored dev artifacts `custom-gcl` (~55 MB) and `.venv` are excluded so
# the hermetic derivation stays small. `lib.fileset` is used instead of
# `filterSource`: the `builtins.filterSource` primop is unreliable here.
src =
let
repo = ./.;
in
lib.fileset.toSource {
root = repo;
fileset =
lib.fileset.unions [
(lib.fileset.fromSource (repo + "/go.mod"))
(lib.fileset.fromSource (repo + "/go.sum"))
(lib.fileset.fromSource (repo + "/cmd"))
(lib.fileset.fromSource (repo + "/internal"))
];
};

buildPen = pkgs: pkgs.buildGoModule {
pname = "pen-fun";
version = version;
src = src;
subPackages = [ "cmd/pen-fun" ];
vendorHash = vendorHash;
ldflags = [
"-s"
"-w"
"-X"
"github.com/Neon-Genesis-Linux/pen-bot/internal/core.Version=${version}"
"-X"
"github.com/Neon-Genesis-Linux/pen-bot/internal/core.Commit=${commit}"
];
};
in {
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
packages = with pkgs; [
devShells = lib.genAttrs systems (system: {
default = nixpkgs.legacyPackages.${system}.mkShell {
packages = with nixpkgs.legacyPackages.${system}; [
go_1_26
golangci-lint
gofumpt
Expand All @@ -19,7 +64,19 @@
yamlfmt
dockerfmt
];
# custom-gcl (golangci-lint + NilAway) is built from .custom-gcl.yml at
# activation, mirroring .github/workflows/ci.yml. Network is available in
# a dev shell, and the guard skips rebuilding when it already exists.
shellHook = ''
if [ ! -x ./custom-gcl ]; then
golangci-lint custom
fi
'';
};
});

packages = lib.genAttrs systems (system: {
default = buildPen nixpkgs.legacyPackages.${system};
});
};
}
11 changes: 6 additions & 5 deletions internal/core/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import (
"github.com/Neon-Genesis-Linux/pen-bot/internal/db"
)

// Start connects the bot to Discord, syncs the registered commands, and blocks
// until ctx is cancelled or the process is interrupted. It reads the intents
// and command definitions once, at startup, so anything registered afterwards
// has no effect.
var (
Version = "dev"
Commit = "dev"
)

func Start(ctx context.Context, token string, guildIDs []snowflake.ID) error {
slog.Info("starting pen bot...")
slog.Info("starting pen bot...", "version", Version, "commit", Commit)
slog.Info("disgo version", slog.String("version", disgo.Version))

if len(guildIDs) > 0 {
Expand Down
Loading