diff --git a/.gitea/workflows/docker.yml b/.gitea/workflows/docker.yml index cd0fefd..e78ce02 100644 --- a/.gitea/workflows/docker.yml +++ b/.gitea/workflows/docker.yml @@ -2,20 +2,41 @@ name: docker on: push: branches: [main] + tags: ['v*'] + workflow_dispatch: jobs: build-and-push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ${{ secrets.REGISTRY }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Resolve image metadata + id: meta + shell: bash + run: | + set -euo pipefail + owner="${{ github.repository_owner }}" + repo="${{ github.event.repository.name }}" + image="${{ secrets.IMAGE_NAME }}" + if [ -z "$image" ]; then + echo "::error::IMAGE_NAME secret is empty." + exit 1 + fi + { + echo "owner=$owner" + echo "repo=$repo" + echo "image=$image" + } >> "$GITHUB_OUTPUT" - uses: docker/build-push-action@v6 with: context: . + file: ./Dockerfile push: true build-args: | VCS_REF=${{ github.sha }} @@ -23,3 +44,56 @@ jobs: tags: | ${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:latest ${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:${{ github.sha }} + - name: Link package to repository + shell: bash + env: + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} + PACKAGE_OWNER: ${{ steps.meta.outputs.owner }} + PACKAGE_NAME: ${{ steps.meta.outputs.repo }} + REPO_NAME: ${{ steps.meta.outputs.repo }} + run: | + set -euo pipefail + token="${REGISTRY_PASSWORD:-${REGISTRY_TOKEN:-}}" + if [ -z "$token" ]; then + echo "::error::Registry token/password is empty. Set REGISTRY_PASSWORD or REGISTRY_TOKEN." + exit 1 + fi + python3 - <<'PY' + import json + import os + import sys + import urllib.error + import urllib.parse + import urllib.request + + owner = os.environ["PACKAGE_OWNER"] + package = os.environ["PACKAGE_NAME"] + repo = os.environ["REPO_NAME"] + token = os.environ["REGISTRY_PASSWORD"] or os.environ["REGISTRY_TOKEN"] + base = "https://gitea.reversed.dev/api/v1" + headers = { + "Authorization": f"token {token}", + "Accept": "application/json", + } + + latest_url = f"{base}/packages/{urllib.parse.quote(owner)}/container/{urllib.parse.quote(package)}/-/latest" + req = urllib.request.Request(latest_url, headers=headers) + with urllib.request.urlopen(req) as resp: + current = json.load(resp) + + linked_repo = (current.get("repository") or {}).get("name") + if linked_repo == repo: + print(f"package already linked to {owner}/{repo}") + sys.exit(0) + + link_url = f"{base}/packages/{urllib.parse.quote(owner)}/container/{urllib.parse.quote(package)}/-/link/{urllib.parse.quote(repo)}" + link_req = urllib.request.Request(link_url, data=b"", method="POST", headers=headers) + try: + with urllib.request.urlopen(link_req) as resp: + print(f"linked package to {owner}/{repo}, status={resp.status}") + except urllib.error.HTTPError as exc: + body = exc.read().decode(errors="replace") + print(f"link failed: status={exc.code} body={body}") + raise + PY diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..665aed1 --- /dev/null +++ b/TODO.md @@ -0,0 +1,72 @@ +# TODO + +Ideas to expand Jellomator without turning it into a heavy app. + +## Product + +- Add drag-and-drop reordering for service cards. +- Add pinned or featured services to keep key links at the top. +- Add per-service badges, such as `New`, `Internal`, or `External`. +- Add an optional note field for each link, shown on hover or in a detail view. +- Add multi-category support instead of a single category string. +- Add a compact view toggle for dense dashboards. +- Add keyboard shortcuts for search and quick launch. +- Add a public read-only mode that hides admin-only services. + +## Admin UX + +- Add bulk edit actions for enable/disable, category, and deletion. +- Add duplicate-link cloning from an existing card. +- Add inline validation for URL format and icon file size. +- Add image cropping or center-fit controls for uploaded icons. +- Add a safer delete flow with a dependency-free confirmation modal. +- Add a “preview as public” toggle in the admin panel. +- Add recent changes / audit history for link updates. + +## Presets + +- Add more service presets for common self-hosted apps, such as Paperless-ngx, Immich, Grafana, Home Assistant, and Vaultwarden. +- Add preset grouping so Arr*, media, download, and utilities are separated. +- Add preset templates with configurable base URLs and ports. +- Add an import flow for JSON presets so users can seed many services at once. + +## Authentication and Security + +- Add session expiry and idle timeout controls. +- Add optional TOTP-based 2FA for admin accounts. +- Add CSRF protection if cookie-authenticated state-changing requests need it. +- Add a login attempt rate limit with temporary lockout. +- Add an admin-only password reset flow for recovery. + +## Data and Backup + +- Add SQLite backup and restore from the admin UI. +- Add an export/import feature for all services and icons. +- Add database migration checks on startup. +- Add soft-delete with restore for accidental removals. +- Add scheduled automatic backups of the SQLite file. + +## API and Integration + +- Add a JSON API endpoint for public service listings. +- Add health and readiness endpoints for container orchestration. +- Add support for external status checks to mark services offline. +- Add service response-time badges for launch targets. +- Add Open Graph metadata for nicer shared links. + +## UI Polish + +- Add animated empty states for no services and no search results. +- Add richer icon fallbacks with initials and category colors. +- Add a subtle background pattern or gradient mesh to the hero section. +- Add toast notifications for save, delete, and upload actions. +- Add theme settings for alternate red, amber, or slate accents. +- Add better mobile navigation for the admin area. + +## Operations + +- Add a Docker healthcheck. +- Add automated build verification in CI after the image is published. +- Add release notes generated from commits. +- Add a minimal seed-reset command for local development. +- Add structured logging for auth and CRUD events.