Link Gitea package to repository
All checks were successful
docker / build-and-push (push) Successful in 52s
All checks were successful
docker / build-and-push (push) Successful in 52s
This commit is contained in:
@@ -2,20 +2,41 @@ name: docker
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
tags: ['v*']
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-push:
|
build-and-push:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
- uses: docker/login-action@v3
|
- uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY }}
|
registry: ${{ secrets.REGISTRY }}
|
||||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
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
|
- uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
push: true
|
push: true
|
||||||
build-args: |
|
build-args: |
|
||||||
VCS_REF=${{ github.sha }}
|
VCS_REF=${{ github.sha }}
|
||||||
@@ -23,3 +44,56 @@ jobs:
|
|||||||
tags: |
|
tags: |
|
||||||
${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:latest
|
${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:latest
|
||||||
${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:${{ github.sha }}
|
${{ 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
|
||||||
|
|||||||
72
TODO.md
Normal file
72
TODO.md
Normal file
@@ -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.
|
||||||
Reference in New Issue
Block a user