diff --git a/.github/workflows/dockerhub-publish.yml b/.github/workflows/dockerhub-publish.yml index 7f3e323..1f63324 100644 --- a/.github/workflows/dockerhub-publish.yml +++ b/.github/workflows/dockerhub-publish.yml @@ -16,6 +16,23 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Prepare release notes from template + id: notes + shell: bash + run: | + VERSION_REF="${GITHUB_REF##*/}" # e.g. v1.2.3 + TEMPLATE="RELEASE_NOTES_TEMPLATE.md" + if [ -f "$TEMPLATE" ]; then + sed "s/\${VERSION}/${VERSION_REF}/g" "$TEMPLATE" > RELEASE_NOTES.md + else + echo "# MTG Python Deckbuilder ${VERSION_REF}" > RELEASE_NOTES.md + echo >> RELEASE_NOTES.md + echo "Automated release." >> RELEASE_NOTES.md + fi + # Escape newlines for label usage + DESC=$(awk 'BEGIN{ORS="\\n"} {print}' RELEASE_NOTES.md) + echo "desc=$DESC" >> $GITHUB_OUTPUT + - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -38,6 +55,10 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest + labels: | + org.opencontainers.image.title=MTG Python Deckbuilder + org.opencontainers.image.version=${{ github.ref_name }} + org.opencontainers.image.description=${{ steps.notes.outputs.desc }} - name: Build and push uses: docker/build-push-action@v6 diff --git a/README.md b/README.md index fd4fa28..a8ce92f 100644 Binary files a/README.md and b/README.md differ diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e0ee89a..3eeb0e8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,7 @@ # MTG Python Deckbuilder v1.1.0 Release Notes +Note: Future releases will generate this file from `RELEASE_NOTES_TEMPLATE.md` automatically in CI. + ## Highlights - Headless mode via submenu in the main menu (auto-runs single config; lists multiple as "Commander - Theme1, Theme2, Theme3"; `deck.json` shows as "Default") - Config precedence: CLI > env > JSON > defaults; honors `ideal_counts` in JSON diff --git a/code/headless_runner.py b/code/headless_runner.py index 4130409..66cec5d 100644 --- a/code/headless_runner.py +++ b/code/headless_runner.py @@ -6,7 +6,7 @@ import os from typing import Any, Dict, List, Optional from pathlib import Path -from code.deck_builder.builder import DeckBuilder +from deck_builder.builder import DeckBuilder """Headless (non-interactive) runner. @@ -159,10 +159,12 @@ def run( if csv_path: base = os.path.splitext(os.path.basename(csv_path))[0] builder.export_decklist_text(filename=base + '.txt') - if hasattr(builder, 'export_run_config_json'): + # Headless policy: do NOT export JSON by default. Opt-in with HEADLESS_EXPORT_JSON=1 + allow_json = (os.getenv('HEADLESS_EXPORT_JSON', '').strip().lower() in {'1','true','yes','on'}) + if allow_json and hasattr(builder, 'export_run_config_json'): try: cfg_path_env = os.getenv('DECK_CONFIG') - if cfg_path_env: + if cfg_path_env and os.path.isdir(os.path.dirname(cfg_path_env) or '.'): cfg_dir = os.path.dirname(cfg_path_env) or '.' elif os.path.isdir('/app/config'): cfg_dir = '/app/config' @@ -170,8 +172,8 @@ def run( cfg_dir = 'config' os.makedirs(cfg_dir, exist_ok=True) builder.export_run_config_json(directory=cfg_dir, filename=base + '.json') - # If an explicit DECK_CONFIG path is given, also write to exactly that path - if cfg_path_env: + # If an explicit DECK_CONFIG path is given to a file, write exactly there as well + if cfg_path_env and os.path.splitext(cfg_path_env)[1].lower() == '.json': cfg_dir2 = os.path.dirname(cfg_path_env) or '.' cfg_name2 = os.path.basename(cfg_path_env) os.makedirs(cfg_dir2, exist_ok=True) diff --git a/config/deck.json b/config/deck.json index 57f247d..3faeb45 100644 --- a/config/deck.json +++ b/config/deck.json @@ -1,8 +1,8 @@ { "commander": "Aang, Airbending Master", - "primary_tag": "Experience Counters", - "secondary_tag": "Token Creation", - "tertiary_tag": null, + "primary_tag": "Exile Matters", + "secondary_tag": "Airbending", + "tertiary_tag": "Token Creation", "bracket_level": 4, "use_multi_theme": true, "add_lands": true,