mirror of
https://github.com/rommapp/romm.git
synced 2026-03-03 02:27:00 +00:00
get branch_name and version from backend
This commit is contained in:
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'romm version'
|
||||
description: "romm version"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
@@ -18,23 +18,32 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set environment variables
|
||||
run: echo "GIT_BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set version
|
||||
run: sed -i 's/<version>/'"${{ inputs.version }}"'/' backend/__version__.py
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
|
||||
7
.github/workflows/pytest.yml
vendored
7
.github/workflows/pytest.yml
vendored
@@ -37,23 +37,29 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install mariadb connectors
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libmariadb3 libmariadb-dev
|
||||
|
||||
- name: Install poetry
|
||||
run: pipx install poetry
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
cache: 'poetry'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
poetry install --sync
|
||||
|
||||
- name: Initiate database
|
||||
run: |
|
||||
mysql --host 127.0.0.1 --port ${{ job.services.mariadb.ports['3306'] }} -uroot -ppasswd -e "GRANT ALL PRIVILEGES ON romm_test.* TO 'romm_test'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;"
|
||||
|
||||
- name: Run python tests
|
||||
env:
|
||||
DB_HOST: 127.0.0.1
|
||||
@@ -61,6 +67,7 @@ jobs:
|
||||
run: |
|
||||
cd backend
|
||||
poetry run pytest -vv --maxfail=10 --junitxml=pytest-report.xml .
|
||||
|
||||
- name: Publish test results
|
||||
uses: EnricoMi/publish-unit-test-result-action/composite@v2
|
||||
if: always()
|
||||
|
||||
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -38,7 +38,7 @@
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "export $(cat .env | xargs); docker exec -i mariadb mariadb -u root -p$DB_ROOT_PASSWD < backend/romm_test/setup.sql",
|
||||
"command": "export $(cat .env | xargs); docker exec -i mariadb mysql -u root -p$DB_ROOT_PASSWD < backend/romm_test/setup.sql",
|
||||
"label": "Setup development environment migrations [docker] (2)",
|
||||
"problemMatcher": []
|
||||
},
|
||||
|
||||
@@ -31,9 +31,8 @@ Then initialize the virtual environment and install the dependencies
|
||||
poetry shell
|
||||
# Fix disable parallel installation stuck: $> poetry config experimental.new-installer false
|
||||
# Fix Loading macOS/linux stuck: $> export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
|
||||
# Fix mariadb install on linux: $> sudo apt install libmariadb3 libmariadb-dev
|
||||
# Fix mariadb connector/c >= 3.3.1: https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/c/install/#Installation_via_Package_Repository_(Linux)
|
||||
poetry install
|
||||
# Fix mariadb install on linux https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/c/install/#Installation_via_Package_Repository_(Linux): $> sudo apt install libmariadb3 libmariadb-dev
|
||||
poetry install --no-root
|
||||
```
|
||||
|
||||
### - Spin up mariadb in docker
|
||||
@@ -87,8 +86,7 @@ npm run dev
|
||||
### - Create the test user and database with root user
|
||||
|
||||
```sh
|
||||
docker exec -i mariadb mysql -u root -p<root password> < backend/romm_test/setup.sql # for amd images
|
||||
docker exec -i mariadb mariadb -u root -p<root password> < backend/romm_test/setup.sql # for arm images
|
||||
docker exec -i mariadb mysql -u root -p<root password> < backend/romm_test/setup.sql
|
||||
```
|
||||
|
||||
### - Run tests
|
||||
|
||||
1
backend/__version__.py
Normal file
1
backend/__version__.py
Normal file
@@ -0,0 +1 @@
|
||||
__version__ = '<version>'
|
||||
@@ -1,6 +1,7 @@
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from main import app
|
||||
from utils import get_version
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
@@ -9,6 +10,7 @@ def test_heartbeat():
|
||||
response = client.get("/heartbeat")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"VERSION" : get_version(),
|
||||
"ROMM_AUTH_ENABLED": True,
|
||||
"WATCHER": {
|
||||
"ENABLED": True,
|
||||
|
||||
@@ -30,6 +30,7 @@ from utils.auth import (
|
||||
CustomCSRFMiddleware,
|
||||
create_default_admin_user,
|
||||
)
|
||||
from utils import get_version
|
||||
|
||||
app = FastAPI(title="RomM API", version="0.1.0")
|
||||
|
||||
@@ -78,6 +79,7 @@ app.mount("/ws", socket_app)
|
||||
@app.get("/heartbeat")
|
||||
def heartbeat():
|
||||
return {
|
||||
"VERSION": get_version(),
|
||||
"ROMM_AUTH_ENABLED": ROMM_AUTH_ENABLED,
|
||||
"WATCHER": {
|
||||
"ENABLED": ENABLE_RESCAN_ON_FILESYSTEM_CHANGE,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import re
|
||||
import numpy as np
|
||||
import subprocess as sp
|
||||
from __version__ import __version__
|
||||
|
||||
LANGUAGES = [
|
||||
("Ar", "Arabic"),
|
||||
@@ -119,3 +120,16 @@ def get_file_extension(rom: dict) -> str:
|
||||
if not rom["multi"]
|
||||
else ""
|
||||
)
|
||||
|
||||
|
||||
def get_version() -> str | None:
|
||||
"""Returns current version or branch name."""
|
||||
if not __version__ == "<version>":
|
||||
return __version__
|
||||
else:
|
||||
try:
|
||||
output = str(sp.check_output(["git", "branch"], universal_newlines=True))
|
||||
except sp.CalledProcessError:
|
||||
return None
|
||||
branch = [a for a in output.split("\n") if a.find("*") >= 0][0]
|
||||
return branch[branch.find("*") + 2 :]
|
||||
|
||||
@@ -19,7 +19,7 @@ from config import (
|
||||
DEFAULT_URL_COVER_S,
|
||||
DEFAULT_PATH_COVER_S,
|
||||
DEFAULT_WIDTH_COVER_S,
|
||||
DEFAULT_HEIGHT_COVER_S
|
||||
DEFAULT_HEIGHT_COVER_S,
|
||||
)
|
||||
from config.config_loader import config
|
||||
from exceptions.fs_exceptions import (
|
||||
@@ -30,12 +30,10 @@ from exceptions.fs_exceptions import (
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# ========= Resources utils =========
|
||||
class CoverSize(Enum):
|
||||
SMALL = 'small'
|
||||
BIG = 'big'
|
||||
SMALL = "small"
|
||||
BIG = "big"
|
||||
|
||||
|
||||
def _cover_exists(fs_slug: str, rom_name: str, size: CoverSize):
|
||||
@@ -49,13 +47,15 @@ def _cover_exists(fs_slug: str, rom_name: str, size: CoverSize):
|
||||
True if cover exists in filesystem else False
|
||||
"""
|
||||
return bool(
|
||||
os.path.exists(f"{RESOURCES_BASE_PATH}/{fs_slug}/{rom_name}/cover/{size.value}.png")
|
||||
os.path.exists(
|
||||
f"{RESOURCES_BASE_PATH}/{fs_slug}/{rom_name}/cover/{size.value}.png"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _resize_cover(cover_path: str, size: CoverSize) -> None:
|
||||
"""Resizes the cover image to the standard size
|
||||
|
||||
|
||||
Args:
|
||||
cover_path: path where the original cover were stored
|
||||
size: size of the cover
|
||||
@@ -64,12 +64,12 @@ def _resize_cover(cover_path: str, size: CoverSize) -> None:
|
||||
if cover.size[1] > DEFAULT_HEIGHT_COVER_L:
|
||||
if size == CoverSize.BIG:
|
||||
big_dimensions = (DEFAULT_WIDTH_COVER_L, DEFAULT_HEIGHT_COVER_L)
|
||||
background = Image.new('RGBA', big_dimensions, (0, 0, 0, 0))
|
||||
background = Image.new("RGBA", big_dimensions, (0, 0, 0, 0))
|
||||
cover.thumbnail(big_dimensions)
|
||||
offset = (int(round(((DEFAULT_WIDTH_COVER_L - cover.size[0]) / 2), 0)), 0)
|
||||
elif size == CoverSize.SMALL:
|
||||
small_dimensions = (DEFAULT_WIDTH_COVER_S, DEFAULT_HEIGHT_COVER_S)
|
||||
background = Image.new('RGBA', small_dimensions, (0, 0, 0, 0))
|
||||
background = Image.new("RGBA", small_dimensions, (0, 0, 0, 0))
|
||||
cover.thumbnail(small_dimensions)
|
||||
offset = (int(round(((DEFAULT_WIDTH_COVER_S - cover.size[0]) / 2), 0)), 0)
|
||||
else:
|
||||
@@ -116,7 +116,9 @@ def get_cover(
|
||||
) -> dict:
|
||||
q_rom_name = quote(rom_name)
|
||||
# Cover small
|
||||
if (overwrite or not _cover_exists(fs_slug, rom_name, CoverSize.SMALL)) and url_cover:
|
||||
if (
|
||||
overwrite or not _cover_exists(fs_slug, rom_name, CoverSize.SMALL)
|
||||
) and url_cover:
|
||||
_store_cover(fs_slug, rom_name, url_cover, CoverSize.SMALL)
|
||||
path_cover_s = (
|
||||
_get_cover_path(fs_slug, q_rom_name, CoverSize.SMALL)
|
||||
@@ -293,7 +295,9 @@ def get_roms(fs_slug: str):
|
||||
]
|
||||
|
||||
|
||||
def get_rom_file_size(roms_path: str, file_name: str, multi: bool, multi_files: list = []):
|
||||
def get_rom_file_size(
|
||||
roms_path: str, file_name: str, multi: bool, multi_files: list = []
|
||||
):
|
||||
files = (
|
||||
[f"{LIBRARY_BASE_PATH}/{roms_path}/{file_name}"]
|
||||
if not multi
|
||||
|
||||
@@ -31,8 +31,8 @@ def test_get_cover():
|
||||
rom_name="Paper Mario",
|
||||
)
|
||||
|
||||
assert DEFAULT_PATH_COVER_S in cover["path_cover_s"]
|
||||
assert DEFAULT_PATH_COVER_L in cover["path_cover_l"]
|
||||
assert "n64/Paper%20Mario/cover/small.png" in cover["path_cover_s"]
|
||||
assert "n64/Paper%20Mario/cover/big.png" in cover["path_cover_l"]
|
||||
|
||||
# Game: Paper Mario (USA).z64
|
||||
cover = get_cover(
|
||||
|
||||
@@ -4,14 +4,17 @@ import cookie from "js-cookie";
|
||||
import storeAuth from "@/stores/auth";
|
||||
import Notification from "@/components/Notification.vue";
|
||||
import { api } from "@/services/api";
|
||||
import storeHeartbeat from "@/stores/heartbeat";
|
||||
|
||||
// Props
|
||||
const auth = storeAuth();
|
||||
const heartbeat = storeHeartbeat();
|
||||
|
||||
onBeforeMount(async () => {
|
||||
// Set CSRF token for all requests
|
||||
const { data } = await api.get("/heartbeat");
|
||||
heartbeat.set(data)
|
||||
auth.setEnabled(data.ROMM_AUTH_ENABLED ?? false);
|
||||
// Set CSRF token for all requests
|
||||
api.defaults.headers.common["x-csrftoken"] = cookie.get("csrftoken");
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -3,11 +3,11 @@ import { ref, onBeforeMount, inject } from "vue";
|
||||
import { api } from "@/services/api";
|
||||
import TaskWatcher from "@/components/Settings/General/TaskStatus/TaskWatcher.vue";
|
||||
import TaskScheduler from "@/components/Settings/General/TaskStatus/TaskScheduler.vue";
|
||||
import storeHeartbeat from "@/stores/heartbeat";
|
||||
|
||||
// Props
|
||||
const watcher = ref({});
|
||||
const scheduler = ref({});
|
||||
const emitter = inject("emitter");
|
||||
const heartbeat = storeHeartbeat();
|
||||
|
||||
// Methods
|
||||
const runAllTasks = async () => {
|
||||
@@ -26,12 +26,6 @@ const runAllTasks = async () => {
|
||||
color: "green",
|
||||
});
|
||||
};
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const { data } = await api.get("/heartbeat");
|
||||
watcher.value = data.WATCHER;
|
||||
scheduler.value = data.SCHEDULER;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<v-card rounded="0">
|
||||
@@ -41,7 +35,7 @@ onBeforeMount(async () => {
|
||||
Task Status
|
||||
</v-toolbar-title>
|
||||
<v-toolbar-items>
|
||||
<v-btn @click="runAllTasks"> Run all </v-btn>
|
||||
<v-btn @click="runAllTasks"><v-icon class="mr-1">mdi-play</v-icon> Run all </v-btn>
|
||||
</v-toolbar-items>
|
||||
</v-toolbar>
|
||||
|
||||
@@ -49,12 +43,12 @@ onBeforeMount(async () => {
|
||||
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<task-watcher :watcher="watcher" />
|
||||
<task-watcher :watcher="heartbeat.data.WATCHER" />
|
||||
|
||||
<v-divider class="border-opacity-25" />
|
||||
|
||||
<v-col
|
||||
v-for="task in scheduler"
|
||||
v-for="task in heartbeat.data.SCHEDULER"
|
||||
cols="12"
|
||||
md="4"
|
||||
sm="6"
|
||||
|
||||
11
frontend/src/stores/heartbeat.js
Normal file
11
frontend/src/stores/heartbeat.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
export default defineStore("heartbeat", {
|
||||
state: () => ({ data: {} }),
|
||||
|
||||
actions: {
|
||||
set(data) {
|
||||
this.data = data;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -3,10 +3,11 @@ import { ref } from "vue";
|
||||
import storeAuth from "@/stores/auth";
|
||||
import Settings from "@/views/Settings/ControlPanel/General/Base.vue";
|
||||
import Users from "@/views/Settings/ControlPanel/Users/Base.vue";
|
||||
import version from "../../../../package";
|
||||
import storeHeartbeat from "@/stores/heartbeat";
|
||||
|
||||
// Props
|
||||
const auth = storeAuth();
|
||||
const heartbeat = storeHeartbeat();
|
||||
const tab = ref("general");
|
||||
</script>
|
||||
<template>
|
||||
@@ -47,7 +48,7 @@ const tab = ref("general");
|
||||
<v-bottom-navigation :elevation="0" height="36" class="text-caption">
|
||||
<v-row class="align-center justify-center" no-gutters>
|
||||
<span class="text-romm-accent-1">RomM</span>
|
||||
<span class="ml-1">{{ version.version }}</span>
|
||||
<span class="ml-1">{{ heartbeat.data.VERSION }}</span>
|
||||
</v-row>
|
||||
</v-bottom-navigation>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user