mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-21 04:15:34 -04:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be4f71e5df | ||
|
|
78ff4bb875 | ||
|
|
26924ab054 | ||
|
|
c533da1c21 |
5
.github/workflows/build-package.yml
vendored
5
.github/workflows/build-package.yml
vendored
@@ -6,6 +6,9 @@ on:
|
|||||||
tag:
|
tag:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
ref:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-frontend:
|
build-frontend:
|
||||||
@@ -15,6 +18,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout 🛎
|
- name: Checkout 🛎
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
|
|
||||||
- name: Setup node env 🏗
|
- name: Setup node env 🏗
|
||||||
uses: actions/setup-node@v4.0.0
|
uses: actions/setup-node@v4.0.0
|
||||||
|
|||||||
5
.github/workflows/publish.yml
vendored
5
.github/workflows/publish.yml
vendored
@@ -9,6 +9,9 @@ on:
|
|||||||
tags:
|
tags:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
ref:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
secrets:
|
secrets:
|
||||||
DOCKERHUB_USERNAME:
|
DOCKERHUB_USERNAME:
|
||||||
required: true
|
required: true
|
||||||
@@ -21,6 +24,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
|
|
||||||
- name: Log in to the Container registry (ghcr.io)
|
- name: Log in to the Container registry (ghcr.io)
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
|||||||
7
.github/workflows/release.yml
vendored
7
.github/workflows/release.yml
vendored
@@ -60,12 +60,16 @@ jobs:
|
|||||||
uses: ./.github/workflows/test-backend.yml
|
uses: ./.github/workflows/test-backend.yml
|
||||||
needs:
|
needs:
|
||||||
- commit-version-bump
|
- commit-version-bump
|
||||||
|
with:
|
||||||
|
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
|
||||||
|
|
||||||
frontend-tests:
|
frontend-tests:
|
||||||
name: "Frontend Tests"
|
name: "Frontend Tests"
|
||||||
uses: ./.github/workflows/test-frontend.yml
|
uses: ./.github/workflows/test-frontend.yml
|
||||||
needs:
|
needs:
|
||||||
- commit-version-bump
|
- commit-version-bump
|
||||||
|
with:
|
||||||
|
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
|
||||||
|
|
||||||
build-package:
|
build-package:
|
||||||
name: Build Package
|
name: Build Package
|
||||||
@@ -74,6 +78,7 @@ jobs:
|
|||||||
- commit-version-bump
|
- commit-version-bump
|
||||||
with:
|
with:
|
||||||
tag: ${{ github.event.release.tag_name }}
|
tag: ${{ github.event.release.tag_name }}
|
||||||
|
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -90,7 +95,9 @@ jobs:
|
|||||||
- backend-tests
|
- backend-tests
|
||||||
- frontend-tests
|
- frontend-tests
|
||||||
- build-package
|
- build-package
|
||||||
|
- commit-version-bump
|
||||||
with:
|
with:
|
||||||
|
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
|
||||||
tag: ${{ github.event.release.tag_name }}
|
tag: ${{ github.event.release.tag_name }}
|
||||||
tags: |
|
tags: |
|
||||||
hkotel/mealie:latest
|
hkotel/mealie:latest
|
||||||
|
|||||||
6
.github/workflows/test-backend.yml
vendored
6
.github/workflows/test-backend.yml
vendored
@@ -2,6 +2,10 @@ name: Backend Lint and Test
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
ref:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
@@ -43,6 +47,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
|
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
|
|||||||
6
.github/workflows/test-frontend.yml
vendored
6
.github/workflows/test-frontend.yml
vendored
@@ -2,6 +2,10 @@ name: Frontend Lint and Test
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
ref:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
@@ -10,6 +14,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout 🛎
|
- name: Checkout 🛎
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
|
|
||||||
- name: Setup node env 🏗
|
- name: Setup node env 🏗
|
||||||
uses: actions/setup-node@v4.0.0
|
uses: actions/setup-node@v4.0.0
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ To deploy mealie on your local network, it is highly recommended to use Docker t
|
|||||||
We've gone through a few versions of Mealie v1 deployment targets. We have settled on a single container deployment, and we've begun publishing the nightly container on github containers. If you're looking to move from the old nightly (split containers _or_ the omni image) to the new nightly, there are a few things you need to do:
|
We've gone through a few versions of Mealie v1 deployment targets. We have settled on a single container deployment, and we've begun publishing the nightly container on github containers. If you're looking to move from the old nightly (split containers _or_ the omni image) to the new nightly, there are a few things you need to do:
|
||||||
|
|
||||||
1. Take a backup just in case!
|
1. Take a backup just in case!
|
||||||
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.13.0`
|
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.13.1`
|
||||||
3. Take the external port from the frontend container and set that as the port mapped to port `9000` on the new container. The frontend is now served on port 9000 from the new container, so it will need to be mapped for you to have access.
|
3. Take the external port from the frontend container and set that as the port mapped to port `9000` on the new container. The frontend is now served on port 9000 from the new container, so it will need to be mapped for you to have access.
|
||||||
4. Restart the container
|
4. Restart the container
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
|
|||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
mealie:
|
mealie:
|
||||||
image: ghcr.io/mealie-recipes/mealie:v3.13.0 # (3)
|
image: ghcr.io/mealie-recipes/mealie:v3.13.1 # (3)
|
||||||
container_name: mealie
|
container_name: mealie
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
|
|||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
mealie:
|
mealie:
|
||||||
image: ghcr.io/mealie-recipes/mealie:v3.13.0 # (3)
|
image: ghcr.io/mealie-recipes/mealie:v3.13.1 # (3)
|
||||||
container_name: mealie
|
container_name: mealie
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -904,7 +904,7 @@
|
|||||||
"all-lists": "Összes lista",
|
"all-lists": "Összes lista",
|
||||||
"create-shopping-list": "Bevásárlólista készítése",
|
"create-shopping-list": "Bevásárlólista készítése",
|
||||||
"from-recipe": "Receptből",
|
"from-recipe": "Receptből",
|
||||||
"ingredient-of-recipe": "Ingredient of {recipe}",
|
"ingredient-of-recipe": "{recipe} hozzávalók",
|
||||||
"list-name": "Lista Neve",
|
"list-name": "Lista Neve",
|
||||||
"new-list": "Új lista",
|
"new-list": "Új lista",
|
||||||
"quantity": "Mennyiség: {0}",
|
"quantity": "Mennyiség: {0}",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mealie",
|
"name": "mealie",
|
||||||
"version": "3.13.0",
|
"version": "3.13.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nuxt dev",
|
"dev": "nuxt dev",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ def api_extras(func):
|
|||||||
"""Decorator function to unpack the extras into a dict; requires an "extras" column"""
|
"""Decorator function to unpack the extras into a dict; requires an "extras" column"""
|
||||||
|
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
extras = kwargs.pop("extras")
|
extras = kwargs.pop("extras", None)
|
||||||
|
|
||||||
if extras is None:
|
if extras is None:
|
||||||
extras = []
|
extras = []
|
||||||
|
|||||||
@@ -201,6 +201,16 @@ class RepositoryRecipes(HouseholdRepositoryGeneric[Recipe, RecipeModel]):
|
|||||||
additional_ids = self.session.execute(sa.select(model.id).filter(model.slug.in_(slugs))).scalars().all()
|
additional_ids = self.session.execute(sa.select(model.id).filter(model.slug.in_(slugs))).scalars().all()
|
||||||
return ids + additional_ids
|
return ids + additional_ids
|
||||||
|
|
||||||
|
def update(self, match_value: str | int | UUID4, new_data: dict | Recipe) -> Recipe:
|
||||||
|
new_data = new_data if isinstance(new_data, dict) else new_data.model_dump()
|
||||||
|
|
||||||
|
# Handle explicit group_id injection for related items that require it
|
||||||
|
for organizer_field in ["tags", "recipe_category", "tools"]:
|
||||||
|
for organizer in new_data.get(organizer_field, []):
|
||||||
|
organizer["group_id"] = self.group_id
|
||||||
|
|
||||||
|
return super().update(match_value, new_data)
|
||||||
|
|
||||||
def page_all( # type: ignore
|
def page_all( # type: ignore
|
||||||
self,
|
self,
|
||||||
pagination: PaginationQuery,
|
pagination: PaginationQuery,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "mealie"
|
name = "mealie"
|
||||||
version = "3.13.0"
|
version = "3.13.1"
|
||||||
description = "A Recipe Manager"
|
description = "A Recipe Manager"
|
||||||
authors = [{ name = "Hayden", email = "hay-kot@pm.me" }]
|
authors = [{ name = "Hayden", email = "hay-kot@pm.me" }]
|
||||||
license = "AGPL-3.0-only"
|
license = "AGPL-3.0-only"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from datetime import UTC, datetime, timedelta
|
from datetime import UTC, datetime, timedelta
|
||||||
from uuid import UUID
|
from uuid import UUID, uuid4
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
@@ -810,3 +810,48 @@ def test_order_by_rating(user_tuple: tuple[TestUser, TestUser]):
|
|||||||
assert data[0].slug == recipe_2.slug # global rating == 2.5 (avg of 4 and 1)
|
assert data[0].slug == recipe_2.slug # global rating == 2.5 (avg of 4 and 1)
|
||||||
assert data[1].slug == recipe_3.slug # global rating == 3
|
assert data[1].slug == recipe_3.slug # global rating == 3
|
||||||
assert data[2].slug == recipe_1.slug # global rating == 4.25 (avg of 5 and 3.5)
|
assert data[2].slug == recipe_1.slug # global rating == 4.25 (avg of 5 and 3.5)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("route", ["patch", "update"])
|
||||||
|
def test_recipe_inject_organizer_group_id(unique_user: TestUser, route: str):
|
||||||
|
# Regression test for #6802 - Ensure explicit group_id injection works for new organizers
|
||||||
|
database = unique_user.repos
|
||||||
|
recipe = database.recipes.create(
|
||||||
|
Recipe(
|
||||||
|
user_id=unique_user.user_id,
|
||||||
|
group_id=unique_user.group_id,
|
||||||
|
name=random_string(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
new_tag_name = random_string()
|
||||||
|
new_cat_name = random_string()
|
||||||
|
new_tool_name = random_string()
|
||||||
|
|
||||||
|
patch_data = Recipe(
|
||||||
|
name=recipe.name,
|
||||||
|
tags=[new_tag_name],
|
||||||
|
recipe_category=[new_cat_name],
|
||||||
|
tools=[{"id": uuid4(), "name": new_tool_name, "slug": new_tool_name}],
|
||||||
|
)
|
||||||
|
|
||||||
|
# This should not raise IntegrityError or TypeError
|
||||||
|
update_func = database.recipes.patch if route == "patch" else database.recipes.update
|
||||||
|
if route == "patch":
|
||||||
|
updated_recipe = update_func(recipe.slug, patch_data.model_dump(exclude_unset=True))
|
||||||
|
elif route == "update":
|
||||||
|
updated_recipe = update_func(recipe.slug, patch_data.model_dump(exclude_unset=True))
|
||||||
|
|
||||||
|
assert updated_recipe
|
||||||
|
|
||||||
|
assert updated_recipe.tags
|
||||||
|
assert len(updated_recipe.tags) == 1
|
||||||
|
assert updated_recipe.tags[0].name == new_tag_name
|
||||||
|
|
||||||
|
assert updated_recipe.recipe_category
|
||||||
|
assert len(updated_recipe.recipe_category) == 1
|
||||||
|
assert updated_recipe.recipe_category[0].name == new_cat_name
|
||||||
|
|
||||||
|
assert updated_recipe.tools
|
||||||
|
assert len(updated_recipe.tools) == 1
|
||||||
|
assert updated_recipe.tools[0].name == new_tool_name
|
||||||
|
|||||||
Reference in New Issue
Block a user