Author SHA1 Message Date
ahmza 6e4659970f Add Velocity forwarding support
Publish Packwiz site / publish (push) Successful in 1m28s
2026-09-05 00:31:51 +01:00
ahmza acbcb24bf6 Retire Playground Packwiz channel
Publish Packwiz site / publish (push) Successful in 1m25s
2026-09-05 00:12:51 +01:00
ahmza 340b91aad7 Build Packwiz hashes in published images
Publish Packwiz site / publish (push) Successful in 1m53s
2026-09-04 23:27:12 +01:00
ahmza 70cb26e762 Split registry and GitOps credentials
Publish Packwiz site / publish (push) Successful in 1m30s
2026-09-04 12:52:25 +00:00
ahmza a41e119720 Move publishing to organization namespace
Publish Packwiz site / publish (push) Canceled after 0s
2026-09-04 12:46:31 +00:00
10 changed files with 80 additions and 126 deletions
+19 -22
View File
@@ -27,15 +27,12 @@ Stable:
https://mc.ahmza.com/forever/stable/pack.toml
```
### Playground
### Creative Playground Server
Disposable environment for testing mods, updates and configuration changes before considering them for Forever World.
Development:
```text
https://mc.ahmza.com/playground/dev/pack.toml
```
`agsmc-playground` is a disposable creative superflat server that consumes the
Forever stable pack. It does not have an independent Packwiz publication
channel. Upcoming pack changes are validated on `agsmc-forever-staging` through
the Forever development endpoint.
## Repository Structure
@@ -54,13 +51,6 @@ mc-modpacks/
│ ├── config/
│ ├── defaultconfigs/
│ └── README.md
├── playground/
│ ├── pack.toml
│ ├── index.toml
│ ├── mods/
│ ├── config/
│ ├── defaultconfigs/
│ └── README.md
└── deploy/
└── kubernetes/
```
@@ -173,19 +163,26 @@ Pterodactyl is responsible for Java, server process management and resources.
Kubernetes/SWS provides static hosting for the published Packwiz repositories.
The publishing workflow runs [`scripts/build-site.sh`](../scripts/build-site.sh),
which exports committed Git revisions into the documented URL layout, then
builds the multi-architecture image
`tea.ahmza.com/ahmza/mcpacks-site`.
which exports committed Git revisions into the documented URL layout. Source
packs intentionally keep `no-internal-hashes = true`; the workflow runs
`packwiz refresh --build` only against the exported copies under `.build/site`
so the image contains installer-ready hashes without committing generated hash
churn. It then builds the multi-architecture image
`tea.ahmza.com/ahmza.com/mcpacks-site`.
The workflow finally commits that image's immutable OCI digest to
`apps/mcpacks/deployment.yaml` in the `ahmza/k8s-starter-pack` repository.
`apps/mcpacks/deployment.yaml` in the `ahmza.com/k8s-starter-pack` repository.
Argo CD notices that commit and performs the rollout; the workflow does not
hold Kubernetes credentials or change the cluster directly.
The Gitea Actions repository secret `GITEATOKEN` must be able to:
The publishing workflow uses two Gitea Actions repository secrets belonging
to `ci-bot`:
- push packages owned by `ahmza`
- read and write `ahmza/k8s-starter-pack`
- `REGISTRY_TOKEN` can push packages owned by the `ahmza.com` organization
- `GITOPS_TOKEN` can read and write `ahmza.com/k8s-starter-pack`
Keeping these credentials separate ensures that the package token cannot modify
Git repositories and the GitOps token cannot publish packages.
The `latest` image tag exists only to bootstrap the first Argo CD sync and for
human inspection. Normal rollouts use the exact content digest recorded in the
+22 -6
View File
@@ -15,7 +15,7 @@ concurrency:
env:
REGISTRY: tea.ahmza.com
IMAGE_NAME: ahmza/mcpacks-site
IMAGE_NAME: ahmza.com/mcpacks-site
jobs:
publish:
@@ -36,6 +36,17 @@ jobs:
# explicitly ensures /dev still contains today's development branch.
run: git fetch origin main:refs/remotes/origin/main --tags --force
- name: Set up Go for Packwiz
uses: actions/setup-go@v5
with:
go-version: "1.23.x"
cache: false
- name: Install pinned Packwiz
# Packwiz has no stable binary release channel. Pinning the source
# revision makes image builds reproducible instead of following latest.
run: go install github.com/packwiz/packwiz@dfd8b68a4796c763e25bad50265ea1f1233e24f1
- name: Assemble static Packwiz site
env:
EVENT_REF: ${{ gitea.ref }}
@@ -50,8 +61,13 @@ jobs:
refs/tags/*) dev_ref=origin/main ;;
*) dev_ref=$EVENT_SHA ;;
esac
PACKWIZ_BIN="$(go env GOPATH)/bin/packwiz" \
./scripts/build-site.sh "$dev_ref"
test -s .build/site/forever/dev/pack.toml
grep -q '^hash = "[0-9a-f]\{64\}"$' \
.build/site/forever/dev/pack.toml
# Building distribution metadata must not alter tracked source packs.
git diff --exit-code -- forever
- name: Verify tagged release output
if: startsWith(gitea.ref, 'refs/tags/')
@@ -66,8 +82,8 @@ jobs:
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.repository_owner }}
password: ${{ secrets.GITEATOKEN }}
username: ci-bot
password: ${{ secrets.REGISTRY_TOKEN }}
# The SWS runtime image already publishes amd64 and arm64 variants and
# this Dockerfile has no target-architecture RUN commands, so Buildx can
@@ -94,9 +110,9 @@ jobs:
- name: Check out cluster GitOps repository
uses: actions/checkout@v4
with:
repository: ahmza/k8s-starter-pack
repository: ahmza.com/k8s-starter-pack
ref: main
token: ${{ secrets.GITEATOKEN }}
token: ${{ secrets.GITOPS_TOKEN }}
path: _gitops
- name: Record the deployed image in Git
@@ -113,7 +129,7 @@ jobs:
manifest = Path("_gitops/apps/mcpacks/deployment.yaml")
image = sys.argv[1]
prefix = " image: "
repository = "tea.ahmza.com/ahmza/mcpacks-site"
repository = "tea.ahmza.com/ahmza.com/mcpacks-site"
lines = manifest.read_text().splitlines()
matches = [
i for i, line in enumerate(lines)
+1 -1
View File
@@ -7,7 +7,7 @@
FROM ghcr.io/static-web-server/static-web-server:2.44.0@sha256:2c1a7c3e0feaea5859307403b74e1c575f3ec1499094fc077344173d11abaae2
ARG VCS_REF=unknown
LABEL org.opencontainers.image.source="https://tea.ahmza.com/ahmza/mcpacks" \
LABEL org.opencontainers.image.source="https://tea.ahmza.com/ahmza.com/mcpacks" \
org.opencontainers.image.revision="$VCS_REF" \
org.opencontainers.image.description="Static Packwiz repositories for AGS Minecraft servers"
+2 -2
View File
@@ -14,7 +14,7 @@
"pid_limit"
],
"docker_images": {
"Java 21": "ghcr.io/ptero-eggs/yolks:java_21"
"Java 21": "ghcr.io/pterodactyl/yolks:java_21"
},
"file_denylist": [],
"startup": "bash ./start-packwiz.sh {{SERVER_MEMORY}}",
@@ -64,7 +64,7 @@
},
{
"name": "Packwiz Auto Sync",
"description": "Run packwiz-installer before every server start. 1 = enabled, 0 = disabled. Recommended: Forever=0 after deployment if you want explicit promotions; Playground=1.",
"description": "Run packwiz-installer before every server start. 1 = enabled, 0 = disabled. Use 1 for servers that track stable or dev; use 0 only for manually pinned deployments.",
"env_variable": "PACKWIZ_AUTO_SYNC",
"default_value": "1",
"user_viewable": true,
+4 -1
View File
@@ -64,6 +64,8 @@ This automatically excludes client-only mods such as Iris and Sodium.
Some optional client-oriented mods are intentionally installed server-side where their server functionality is useful and does not create an undesirable world dependency.
Proxy Compatible Forge provides authenticated Velocity modern forwarding for the proxied Forever and Playground backends. Its forwarding secret is runtime configuration and must never be committed. Forwarding must remain disabled on the directly accessible Forever staging server.
## Development
Current development builds are published at:
@@ -88,6 +90,7 @@ Forever World releases use repository tags:
forever-v1.0.0
forever-v1.0.1
forever-v1.1.0
forever-v1.1.1
```
A tagged release is published to both:
@@ -99,7 +102,7 @@ A tagged release is published to both:
Release tags and release directories are immutable.
Major mod additions, Minecraft migrations and other potentially disruptive changes should be tested on Playground or a feature branch before being introduced here.
Major mod additions, Minecraft migrations and other potentially disruptive changes should be tested on the Forever staging server or a feature branch before being introduced here.
## Updating a Mod
+4
View File
@@ -243,6 +243,10 @@ metafile = true
file = "mods/ok-zoomer.pw.toml"
metafile = true
[[files]]
file = "mods/proxy-compatible-forge.pw.toml"
metafile = true
[[files]]
file = "mods/resourceful-lib.pw.toml"
metafile = true
@@ -0,0 +1,13 @@
name = "Proxy Compatible Forge"
filename = "proxy-compatible-forge-1.3.1.jar"
side = "server"
[download]
url = "https://cdn.modrinth.com/data/vDyrHl8l/versions/qiZ49HIW/proxy-compatible-forge-1.3.1.jar"
hash-format = "sha512"
hash = "dba5b70fedcb0f5fdc014801ab43e6d048f24b531de8aea5b70ea223760b66ae9fba3033c2ccd9d78793b9ea2f9d3b47ae1f4caa95aa129d989f97e63636b4ab"
[update]
[update.modrinth]
mod-id = "vDyrHl8l"
version = "qiZ49HIW"
+1 -1
View File
@@ -1,6 +1,6 @@
name = "agsmc-forever"
author = "ahmza"
version = "1.1.0"
version = "1.1.1"
pack-format = "packwiz:1.1.0"
[index]
-84
View File
@@ -1,84 +0,0 @@
# Playground
Playground is the experimental Minecraft environment.
Unlike Forever World, this pack is intentionally disposable and exists for testing mods, updates and configuration changes without risking the permanent world.
## Purpose
Use Playground for:
- evaluating new mods
- testing major mod updates
- testing Minecraft/NeoForge upgrades
- experimenting with world generation
- testing compatibility between mods
- testing configuration changes
- reproducing crashes
- validating potential Forever World changes
The world may be reset or replaced at any time.
## Platform
The Minecraft and NeoForge versions may change depending on what is being tested.
Packwiz remains the source of truth for the pack.
## Deployment
Development builds are published at:
```text
https://mc.ahmza.com/playground/dev/pack.toml
```
The Pterodactyl server should normally use:
```text
PACKWIZ_AUTO_SYNC=1
```
so restarting Playground synchronises it with the latest published pack.
## Development
Playground changes can normally be committed directly to `main`:
```bash
cd playground
packwiz add <mod>
packwiz refresh
git add .
git commit -m "Test <mod> in Playground"
git push
```
Feature branches may be used for larger experiments, but are not required for routine testing.
## Promotion to Forever World
A mod working in Playground does not automatically make it suitable for Forever World.
Before promotion consider:
- stability
- maintenance activity
- compatibility
- world-save impact
- dependencies
- performance
- removal behaviour
- future Minecraft upgrade prospects
Mods considered suitable should then be added independently to the Forever pack and tested against the Forever staging server.
## Persistence
Nothing in Playground should be considered permanent.
Worlds, configs and mods may be removed or reset as required.
If something matters, move it into the appropriate version-controlled configuration before relying on it.
+13 -8
View File
@@ -8,10 +8,16 @@ repo_root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
cd "$repo_root"
dev_ref=${1:-HEAD}
packwiz_bin=${PACKWIZ_BIN:-packwiz}
build_root="$repo_root/.build"
site_root="$build_root/site"
work_root="$build_root/work"
if ! command -v "$packwiz_bin" >/dev/null 2>&1; then
echo "Packwiz executable not found: $packwiz_bin" >&2
exit 1
fi
rm -rf "$site_root" "$work_root"
mkdir -p "$site_root/forever/releases" "$work_root"
@@ -30,20 +36,19 @@ export_pack() {
git archive "$revision" "$pack" | tar -x -C "$scratch"
mv "$scratch/$pack" "$destination"
# Source packs intentionally omit internal hashes. Generate the distributable
# index only in the ephemeral image-build tree, never in the Git checkout.
(
cd "$destination"
"$packwiz_bin" refresh --build
)
}
# main is always the development source, including when this script runs for a
# release-tag event whose checked-out commit is intentionally older than main.
export_pack "$dev_ref" forever "$site_root/forever/dev"
# Playground is documented but intentionally incomplete today. Start serving
# it automatically as soon as a committed playground/pack.toml exists.
if export_pack "$dev_ref" playground "$site_root/playground/dev"; then
echo "Published playground development pack from $dev_ref"
else
echo "Skipping playground: $dev_ref has no playground/pack.toml" >&2
fi
# Each forever-vX.Y.Z tag becomes an immutable URL. Version-aware Git sorting
# also identifies the newest release to copy to the stable channel.
release_tags=$(git tag --list 'forever-v*' --sort=-version:refname \