Compare commits

...

4 Commits

Author SHA1 Message Date
mealie-commit-bot[bot]
be4f71e5df chore: bump version to v3.13.1 2026-03-18 22:46:46 +00:00
Brian Choromanski
78ff4bb875 fix: Updated workflows to checkout on commit of commit-version-bump (#7217)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-03-18 17:44:39 -05:00
Sim
26924ab054 fix: #6802 prevent 500 internal server error when patching recipe tags (#6803)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
Co-authored-by: Michael Genson <genson.michael@gmail.com>
2026-03-18 13:45:51 -05:00
Hayden
c533da1c21 chore(l10n): New Crowdin updates (#7271) 2026-03-18 14:16:33 +00:00
15 changed files with 93 additions and 9 deletions

View File

@@ -6,6 +6,9 @@ on:
tag:
required: true
type: string
ref:
required: false
type: string
jobs:
build-frontend:
@@ -15,6 +18,8 @@ jobs:
steps:
- name: Checkout 🛎
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
- name: Setup node env 🏗
uses: actions/setup-node@v4.0.0

View File

@@ -9,6 +9,9 @@ on:
tags:
required: false
type: string
ref:
required: false
type: string
secrets:
DOCKERHUB_USERNAME:
required: true
@@ -21,6 +24,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
- name: Log in to the Container registry (ghcr.io)
uses: docker/login-action@v3

View File

@@ -60,12 +60,16 @@ jobs:
uses: ./.github/workflows/test-backend.yml
needs:
- commit-version-bump
with:
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
frontend-tests:
name: "Frontend Tests"
uses: ./.github/workflows/test-frontend.yml
needs:
- commit-version-bump
with:
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
build-package:
name: Build Package
@@ -74,6 +78,7 @@ jobs:
- commit-version-bump
with:
tag: ${{ github.event.release.tag_name }}
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
publish:
permissions:
@@ -90,7 +95,9 @@ jobs:
- backend-tests
- frontend-tests
- build-package
- commit-version-bump
with:
ref: ${{ needs.commit-version-bump.outputs.commit-sha }}
tag: ${{ github.event.release.tag_name }}
tags: |
hkotel/mealie:latest

View File

@@ -2,6 +2,10 @@ name: Backend Lint and Test
on:
workflow_call:
inputs:
ref:
required: false
type: string
jobs:
tests:
@@ -43,6 +47,8 @@ jobs:
- name: Check out repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
- name: Set up python
uses: actions/setup-python@v5

View File

@@ -2,6 +2,10 @@ name: Frontend Lint and Test
on:
workflow_call:
inputs:
ref:
required: false
type: string
jobs:
lint:
@@ -10,6 +14,8 @@ jobs:
steps:
- name: Checkout 🛎
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
- name: Setup node env 🏗
uses: actions/setup-node@v4.0.0

View File

@@ -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:
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.
4. Restart the container

View File

@@ -10,7 +10,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.13.0 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.13.1 # (3)
container_name: mealie
restart: always
ports:

View File

@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.13.0 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.13.1 # (3)
container_name: mealie
restart: always
ports:

View File

@@ -904,7 +904,7 @@
"all-lists": "Összes lista",
"create-shopping-list": "Bevásárlólista készítése",
"from-recipe": "Receptből",
"ingredient-of-recipe": "Ingredient of {recipe}",
"ingredient-of-recipe": "{recipe} hozzávalók",
"list-name": "Lista Neve",
"new-list": "Új lista",
"quantity": "Mennyiség: {0}",

View File

@@ -1,6 +1,6 @@
{
"name": "mealie",
"version": "3.13.0",
"version": "3.13.1",
"private": true,
"scripts": {
"dev": "nuxt dev",

View File

@@ -9,7 +9,7 @@ def api_extras(func):
"""Decorator function to unpack the extras into a dict; requires an "extras" column"""
def wrapper(*args, **kwargs):
extras = kwargs.pop("extras")
extras = kwargs.pop("extras", None)
if extras is None:
extras = []

View File

@@ -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()
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
self,
pagination: PaginationQuery,

View File

@@ -1,6 +1,6 @@
[project]
name = "mealie"
version = "3.13.0"
version = "3.13.1"
description = "A Recipe Manager"
authors = [{ name = "Hayden", email = "hay-kot@pm.me" }]
license = "AGPL-3.0-only"

View File

@@ -1,5 +1,5 @@
from datetime import UTC, datetime, timedelta
from uuid import UUID
from uuid import UUID, uuid4
import pytest
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[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)
@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

2
uv.lock generated
View File

@@ -862,7 +862,7 @@ wheels = [
[[package]]
name = "mealie"
version = "3.13.0"
version = "3.13.1"
source = { editable = "." }
dependencies = [
{ name = "aiofiles" },