Compare commits
7 Commits
03e1f3b3e7
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8324ecd1e7 | |||
| 0567a1d29b | |||
| f2360cdae8 | |||
| 59245a469d | |||
| ab35e52728 | |||
| d2ce7f0fdc | |||
| a61f3a9c33 |
@@ -1,7 +1,5 @@
|
||||
# This workflow builds and deploys DOStalgia whenever code is pushed to main.
|
||||
# This workflow builds DOStalgia whenever code is pushed to main.
|
||||
# The runner has Docker socket access so it can manage containers on the host.
|
||||
# Parameters match the docker-compose at:
|
||||
# /appdata/dockhand/stacks/unraid/dostalgia/compose.yaml
|
||||
# See: https://docs.gitea.com/usage/actions
|
||||
|
||||
name: Build & Deploy
|
||||
@@ -13,8 +11,6 @@ on:
|
||||
|
||||
env:
|
||||
IMAGE_NAME: dostalgia
|
||||
CONTAINER_NAME: dostalgia
|
||||
DATA_VOLUME: /mnt/cache/appdata/dostalgia
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
@@ -29,34 +25,5 @@ jobs:
|
||||
docker build -t ${{ env.IMAGE_NAME }}:${{ gitea.sha }} .
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ gitea.sha }} ${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
- name: Deploy container
|
||||
run: |
|
||||
docker stop ${{ env.CONTAINER_NAME }} 2>/dev/null || true
|
||||
docker rm ${{ env.CONTAINER_NAME }} 2>/dev/null || true
|
||||
docker run -d \
|
||||
--name ${{ env.CONTAINER_NAME }} \
|
||||
--restart unless-stopped \
|
||||
--network dockernet \
|
||||
-p 8765:8765/tcp \
|
||||
-v ${{ env.DATA_VOLUME }}:/data \
|
||||
-e TWITCH_CLIENT_ID='${{ secrets.TWITCH_CLIENT_ID }}' \
|
||||
-e TWITCH_CLIENT_SECRET='${{ secrets.TWITCH_CLIENT_SECRET }}' \
|
||||
${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
- name: Verify container is running
|
||||
run: |
|
||||
sleep 5
|
||||
STATUS=$(docker inspect -f '{{.State.Status}}' ${{ env.CONTAINER_NAME }})
|
||||
if [ "$STATUS" = "running" ]; then
|
||||
echo "✅ DOStalgia container is running"
|
||||
echo "--- last logs ---"
|
||||
docker logs ${{ env.CONTAINER_NAME }} --tail 5
|
||||
echo "✅ DOStalgia deployed!"
|
||||
else
|
||||
echo "❌ Container status: $STATUS"
|
||||
docker logs ${{ env.CONTAINER_NAME }} --tail 30
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Clean up old images
|
||||
run: docker image prune -f --filter "until=24h"
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
|
||||
- name: Extract tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: droideparanoico/dostalgia
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
|
||||
- name: Extract tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: droideparanoico/dostalgia
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -40,3 +40,6 @@ data/saves/*
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Gitea
|
||||
.gitea/
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 droideparanoico
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -104,8 +104,6 @@ docker run -p 8765:8765 -v $(pwd)/data:/data \
|
||||
droideparanoico/dostalgia
|
||||
```
|
||||
|
||||
The pre-built image is published to Docker Hub as [`droideparanoico/dostalgia`](https://hub.docker.com/r/droideparanoico/dostalgia). Published automatically on every GitHub release via CI.
|
||||
|
||||
## Development (without Docker)
|
||||
|
||||
Terminal 1 — Frontend dev server:
|
||||
|
||||
+3
-4
@@ -1,15 +1,14 @@
|
||||
services:
|
||||
dostalgia:
|
||||
image: droideparanoico/dostalgia
|
||||
# Uncomment to build from source instead of using the pre-built image:
|
||||
# build: .
|
||||
container_name: dostalgia
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8765:8765"
|
||||
volumes:
|
||||
# Configure here your data directory if you want persistence.
|
||||
- ./data:/data
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- DOSTALGIA_DATA_DIR=/data
|
||||
restart: unless-stopped
|
||||
- DOSTALGIA_DATA_DIR=/data
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "dostalgia-frontend",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "dostalgia-frontend",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||
"@testing-library/svelte": "^5.3.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "dostalgia-frontend",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<Header onUploadClick={() => uploadTriggered++} />
|
||||
<Header onUploadClick={() => uploadTriggered++} hideUpload={route !== "/"} />
|
||||
|
||||
<main class="container">
|
||||
{#if route === "/"}
|
||||
|
||||
+13
-8
@@ -98,7 +98,8 @@ h3 { font-size: 1.2rem; }
|
||||
/* ═══════════════════════════════════════════════════════════════
|
||||
BUTTONS
|
||||
═══════════════════════════════════════════════════════════════ */
|
||||
.btn {
|
||||
/* Only targets DOStalgia buttons, not js-dos emulator buttons inside .dos-container */
|
||||
.btn.btn:not(.dos-container .btn) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
@@ -111,32 +112,36 @@ h3 { font-size: 1.2rem; }
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-transform: none;
|
||||
height: auto;
|
||||
min-height: 0;
|
||||
line-height: normal;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
.btn:hover {
|
||||
.btn.btn:not(.dos-container .btn):hover {
|
||||
background: var(--phosphor-burn);
|
||||
border-color: var(--phosphor);
|
||||
box-shadow: 0 0 12px var(--phosphor-dark);
|
||||
}
|
||||
.btn:active {
|
||||
.btn.btn:not(.dos-container .btn):active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
.btn-primary.btn-primary:not(.dos-container .btn) {
|
||||
background: var(--phosphor-dark);
|
||||
border-color: var(--phosphor);
|
||||
color: var(--phosphor-glow);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
.btn-primary.btn-primary:not(.dos-container .btn):hover {
|
||||
background: var(--phosphor-dim);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
.btn-danger.btn-danger:not(.dos-container .btn) {
|
||||
border-color: #cc3333;
|
||||
color: #cc3333;
|
||||
}
|
||||
.btn-danger:hover {
|
||||
.btn-danger.btn-danger:not(.dos-container .btn):hover {
|
||||
background: #331111;
|
||||
border-color: #ff4444;
|
||||
color: #ff4444;
|
||||
@@ -187,7 +192,7 @@ input::placeholder {
|
||||
@media (max-width: 640px) {
|
||||
h1 { font-size: 1.5rem; }
|
||||
h2 { font-size: 1.25rem; }
|
||||
.btn { padding: 8px 14px; font-size: 0.85rem; min-height: 40px; }
|
||||
.btn.btn:not(.dos-container .btn) { padding: 8px 14px; font-size: 0.85rem; min-height: 40px; }
|
||||
input, textarea, select { font-size: 16px; } /* prevents iOS zoom */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
let { onUploadClick = () => {} } = $props();
|
||||
let { onUploadClick = () => {}, hideUpload = false } = $props();
|
||||
</script>
|
||||
|
||||
<header class="header">
|
||||
@@ -17,7 +17,9 @@
|
||||
<span class="logo-text">DOSTALGIA</span>
|
||||
</a>
|
||||
<nav>
|
||||
<button class="btn" onclick={onUploadClick}>+ Upload</button>
|
||||
{#if !hideUpload}
|
||||
<button class="btn" onclick={onUploadClick}>+ Upload</button>
|
||||
{/if}
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
← {isSetup ? "Back" : game.title}
|
||||
</button>
|
||||
{#if running}
|
||||
<button class="btn stop-btn" onclick={stopEmulator}>⏹ Stop</button>
|
||||
<button class="btn btn-danger" onclick={stopEmulator}>⏹ Stop</button>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
@@ -211,14 +211,6 @@
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
.link-button:hover { color: var(--phosphor); }
|
||||
.stop-btn {
|
||||
border-color: #cc3333;
|
||||
color: #ff4444;
|
||||
}
|
||||
.stop-btn:hover {
|
||||
background: #331111;
|
||||
box-shadow: 0 0 12px #331111;
|
||||
}
|
||||
|
||||
/* Emulator canvas — always mounted */
|
||||
.dos-container {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 262 KiB After Width: | Height: | Size: 261 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 488 B |
Binary file not shown.
|
After Width: | Height: | Size: 869 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.dostalgia</groupId>
|
||||
<artifactId>dostalgia</artifactId>
|
||||
<version>0.1.0</version>
|
||||
<version>0.1.1</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
|
||||
@@ -53,7 +53,7 @@ public class StaticResource {
|
||||
@GET
|
||||
@jakarta.ws.rs.Path("/api/health")
|
||||
public Response health() {
|
||||
return Response.ok(Map.of("status", "ok", "version", "0.1.0")).build();
|
||||
return Response.ok(Map.of("status", "ok", "version", "0.1.1")).build();
|
||||
}
|
||||
|
||||
private String guessContentType(String name) {
|
||||
|
||||
@@ -23,7 +23,7 @@ class StaticResourceTest {
|
||||
assertInstanceOf(Map.class, entity);
|
||||
Map<?, ?> map = (Map<?, ?>) entity;
|
||||
assertEquals("ok", map.get("status"));
|
||||
assertEquals("0.1.0", map.get("version"));
|
||||
assertEquals("0.1.1", map.get("version"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user