From bd4bd4f29ccc70f9158561d77255ad0501d002e1 Mon Sep 17 00:00:00 2001 From: Admin9705 <24727006+Admin9705@users.noreply.github.com> Date: Sun, 6 Apr 2025 00:54:45 -0400 Subject: [PATCH 1/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e38817e3..21081f52 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Huntarr [Sonarr Edition] - Force Sonarr to Hunt Missing Shows & Upgrade Episode Qualities - +

Want to Help? Click the Star in the Upper-Right Corner! ⭐

From 82bd8e4def36d3057993575aa676125302d40250 Mon Sep 17 00:00:00 2001 From: Admin9705 <24727006+Admin9705@users.noreply.github.com> Date: Sun, 6 Apr 2025 01:01:31 -0400 Subject: [PATCH 2/8] Update docker-image.yml --- .github/workflows/docker-image.yml | 49 +++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 68d257e5..3d0f0f81 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,14 +1,14 @@ name: Docker Build and Push - on: push: branches: - main - dev + tags: + - "*" # This will trigger on any tag push pull_request: branches: - main - jobs: build-and-push: runs-on: ubuntu-latest @@ -18,15 +18,15 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 - + # 2) List files to verify huntarr.py is present - name: List files in directory run: ls -la - + # 3) Set up Docker Buildx - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - + # 4) Log in to Docker Hub - name: Log in to Docker Hub if: github.event_name != 'pull_request' @@ -34,8 +34,14 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - - # 5a) Build & Push if on 'main' branch + + # 5) Extract version from tag if it's a tag push + - name: Extract version from tag + if: startsWith(github.ref, 'refs/tags/') + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + + # 6a) Build & Push if on 'main' branch - name: Build and Push (main) if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' uses: docker/build-push-action@v3 @@ -43,11 +49,10 @@ jobs: context: . push: true tags: | - huntarr/4sonarr:latest - huntarr/4sonarr:py-latest - huntarr/4sonarr:${{ github.sha }} - - # 5b) Build & Push if on 'dev' branch + huntarr/4lidarr:latest + huntarr/4lidarr:${{ github.sha }} + + # 6b) Build & Push if on 'dev' branch - name: Build and Push (dev) if: github.ref == 'refs/heads/dev' && github.event_name != 'pull_request' uses: docker/build-push-action@v3 @@ -55,14 +60,24 @@ jobs: context: . push: true tags: | - huntarr/4sonarr:dev - huntarr/4sonarr:py-dev - huntarr/4sonarr:${{ github.sha }} + huntarr/4lidarr:dev + huntarr/4lidarr:${{ github.sha }} + + # 6c) Build & Push if it's a tag/release + - name: Build and Push (release) + if: startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' + uses: docker/build-push-action@v3 + with: + context: . + push: true + tags: | + huntarr/4lidarr:${{ steps.get_version.outputs.VERSION }} + huntarr/4lidarr:latest - # 5c) Just build on pull requests + # 6d) Just build on pull requests - name: Build (PR) if: github.event_name == 'pull_request' uses: docker/build-push-action@v3 with: context: . - push: false \ No newline at end of file + push: false From 0717fa949eb7925197acff6a62876d78166ef4e6 Mon Sep 17 00:00:00 2001 From: Admin9705 <24727006+Admin9705@users.noreply.github.com> Date: Sun, 6 Apr 2025 01:03:11 -0400 Subject: [PATCH 3/8] Update docker-image.yml --- .github/workflows/docker-image.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 3d0f0f81..ce9f9c01 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -49,8 +49,8 @@ jobs: context: . push: true tags: | - huntarr/4lidarr:latest - huntarr/4lidarr:${{ github.sha }} + huntarr/4sonarr:latest + huntarr/4sonarr:${{ github.sha }} # 6b) Build & Push if on 'dev' branch - name: Build and Push (dev) @@ -60,8 +60,8 @@ jobs: context: . push: true tags: | - huntarr/4lidarr:dev - huntarr/4lidarr:${{ github.sha }} + huntarr/4sonarr:dev + huntarr/4sonarr:${{ github.sha }} # 6c) Build & Push if it's a tag/release - name: Build and Push (release) @@ -71,8 +71,8 @@ jobs: context: . push: true tags: | - huntarr/4lidarr:${{ steps.get_version.outputs.VERSION }} - huntarr/4lidarr:latest + huntarr/4sonarr:${{ steps.get_version.outputs.VERSION }} + huntarr/4sonarr:latest # 6d) Just build on pull requests - name: Build (PR) From 67d92ffdb16b819b1926900fdc0cac75fc98c08f Mon Sep 17 00:00:00 2001 From: Admin9705 <24727006+Admin9705@users.noreply.github.com> Date: Sun, 6 Apr 2025 10:18:43 -0400 Subject: [PATCH 4/8] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a1a5b723..b6f008f4 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ This script continually searches your Sonarr library for shows with missing epis * [Huntarr - Radarr Edition](https://github.com/plexguide/Radarr-Hunter) - Sister version for movies * [Huntarr - Lidarr Edition](https://github.com/plexguide/Lidarr-Hunter) - Sister version for music +* [Huntarr - Readarr Edition](https://github.com/plexguide/Huntarr-Readarr) - Sister version for Books * [Unraid Intel ARC Deployment](https://github.com/plexguide/Unraid_Intel-ARC_Deployment) - Convert videos to AV1 Format (I've saved 325TB encoding to AV1) * Visit [PlexGuide](https://plexguide.com) for more great scripts From 1227948ac375cf64f408b2d2e3b9f5d45d12101a Mon Sep 17 00:00:00 2001 From: Admin9705 <24727006+Admin9705@users.noreply.github.com> Date: Sun, 6 Apr 2025 10:19:01 -0400 Subject: [PATCH 5/8] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6f008f4..c6cba0c3 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ This script continually searches your Sonarr library for shows with missing epis ## Related Projects -* [Huntarr - Radarr Edition](https://github.com/plexguide/Radarr-Hunter) - Sister version for movies -* [Huntarr - Lidarr Edition](https://github.com/plexguide/Lidarr-Hunter) - Sister version for music +* [Huntarr - Radarr Edition](https://github.com/plexguide/Radarr-Hunter) - Sister version for Movies +* [Huntarr - Lidarr Edition](https://github.com/plexguide/Lidarr-Hunter) - Sister version for Music * [Huntarr - Readarr Edition](https://github.com/plexguide/Huntarr-Readarr) - Sister version for Books * [Unraid Intel ARC Deployment](https://github.com/plexguide/Unraid_Intel-ARC_Deployment) - Convert videos to AV1 Format (I've saved 325TB encoding to AV1) * Visit [PlexGuide](https://plexguide.com) for more great scripts From d8dc6ccd45fdb80bef2bf1d770475a44630ac009 Mon Sep 17 00:00:00 2001 From: Zachary Patten Date: Sun, 6 Apr 2025 09:41:07 -0500 Subject: [PATCH 6/8] - Wait for commands to complete to avoid overloading the command queue - Add a minimum donwload queue size to avoid overloading the download queue --- README.md | 41 +++++++++++++++++++++++++++++------------ api.py | 47 ++++++++++++++++++++++++++++++++++++++++++++--- config.py | 23 +++++++++++++++++++++++ main.py | 28 ++++++++++++++++++---------- missing.py | 10 ++++------ upgrade.py | 13 +++++-------- 6 files changed, 123 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index c6cba0c3..76855f28 100644 --- a/README.md +++ b/README.md @@ -98,18 +98,21 @@ My 12-year-old daughter is passionate about singing, dancing, and exploring STEM The following environment variables can be configured: -| Variable | Description | Default | -|------------------------------|-----------------------------------------------------------------------|---------------| -| `API_KEY` | Your Sonarr API key | Required | -| `API_URL` | URL to your Sonarr instance | Required | -| `API_TIMEOUT` | Timeout in seconds for API requests to Sonarr | 60 | -| `MONITORED_ONLY` | Only process monitored shows/episodes | true | -| `HUNT_MISSING_SHOWS` | Maximum missing shows to process per cycle | 1 | -| `HUNT_UPGRADE_EPISODES` | Maximum upgrade episodes to process per cycle | 0 | -| `SLEEP_DURATION` | Seconds to wait after completing a cycle (900 = 15 minutes) | 900 | -| `RANDOM_SELECTION` | Use random selection (`true`) or sequential (`false`) | true | -| `STATE_RESET_INTERVAL_HOURS` | Hours which the processed state files reset (168=1 week, 0=never reset) | 168 | -| `DEBUG_MODE` | Enable detailed debug logging (`true` or `false`) | false | +| Variable | Description | Default | +|-------------------------------|-----------------------------------------------------------------------|---------------| +| `API_KEY` | Your Sonarr API key | Required | +| `API_URL` | URL to your Sonarr instance | Required | +| `API_TIMEOUT` | Timeout in seconds for API requests to Sonarr | 60 | +| `MONITORED_ONLY` | Only process monitored shows/episodes | true | +| `HUNT_MISSING_SHOWS` | Maximum missing shows to process per cycle | 1 | +| `HUNT_UPGRADE_EPISODES` | Maximum upgrade episodes to process per cycle | 0 | +| `SLEEP_DURATION` | Seconds to wait after completing a cycle (900 = 15 minutes) | 900 | +| `RANDOM_SELECTION` | Use random selection (`true`) or sequential (`false`) | true | +| `STATE_RESET_INTERVAL_HOURS` | Hours which the processed state files reset (168=1 week, 0=never reset) | 168 | +| `DEBUG_MODE` | Enable detailed debug logging (`true` or `false`) | false | +| `COMMAND_WAIT_DELAY` | Delay in seconds between checking for command status | 1 | +| `COMMAND_WAIT_ATTEMPTS` | Number of attempts to check for command completeion before giving up | 600 | +| `MINIMUM_DOWNLOAD_QUEUE_SIZE` | Minimum number of items in the download queue before starting a hunt | -1 | ### Detailed Configuration Explanation @@ -146,6 +149,20 @@ The following environment variables can be configured: - When set to `true`, the script will output detailed debugging information about API responses and internal operations. - Useful for troubleshooting issues but can make logs verbose. +- **COMMAND_WAIT_DELAY** + - Certain operations like refreshing and searching happen asynchronously. + - This is the delay in seconds between checking the status of these operations for completion. + - By checking for these to complete before proceeding we can ensure we do not overload the command queue. + - Operations like refreshing update show metadata so this ensures those actions are fully completed before additional operations are performed. + +- **COMMAND_WAIT_ATTEMPTS** + - The number of attempts to wait for an operation to complete before giving up. If a command times out the operation will be considered failed. + +- **MINIMUM_DOWNLOAD_QUEUE_SIZE** + - The minimum number of items in the download queue before a new hunt is initiated. For example if set to `5` then a new hunt will only start when there are 5 or less items marked as `downloading` in the queue. + - This helps prevent overwhelming the queue with too many download requests at once and avoids creating a massive backlog of downloads. + - Set to `-1` to disable this check. + --- ## Installation Methods diff --git a/api.py b/api.py index a2bf6edf..1cf21b94 100644 --- a/api.py +++ b/api.py @@ -5,9 +5,10 @@ """ import requests +import time from typing import List, Dict, Any, Optional, Union from utils.logger import logger, debug_log -from config import API_KEY, API_URL, API_TIMEOUT +from config import API_KEY, API_URL, API_TIMEOUT, COMMAND_WAIT_DELAY, COMMAND_WAIT_ATTEMPTS # Create a session for reuse session = requests.Session() @@ -37,6 +38,31 @@ def sonarr_request(endpoint: str, method: str = "GET", data: Dict = None) -> Opt except requests.exceptions.RequestException as e: logger.error(f"API request error: {e}") return None + +def wait_for_command(command_id: int): + logger.debug(f"Waiting for command {command_id} to complete...") + attempts = 0 + while True: + try: + time.sleep(COMMAND_WAIT_DELAY) + response = sonarr_request(f"command/{command_id}") + logger.debug(f"Command {command_id} Status: {response['status']}") + except Exception as error: + logger.error(f"Error fetching command status on attempt {attempts + 1}: {error}") + return False + + attempts += 1 + + if response['status'].lower() in ['complete', 'completed'] or attempts >= COMMAND_WAIT_ATTEMPTS: + break + + if response['status'].lower() not in ['complete', 'completed']: + logger.warning(f"Command {command_id} did not complete within the allowed attempts.") + return False + + time.sleep(0.5) + + return response['status'].lower() in ['complete', 'completed'] def get_series() -> List[Dict]: """Get all series from Sonarr.""" @@ -57,7 +83,8 @@ def refresh_series(series_id: int) -> Optional[Dict]: "name": "RefreshSeries", "seriesId": series_id } - return sonarr_request("command", method="POST", data=data) + response = sonarr_request("command", method="POST", data=data) + return wait_for_command(response['id']) def episode_search_episodes(episode_ids: List[int]) -> Optional[Dict]: """ @@ -71,7 +98,21 @@ def episode_search_episodes(episode_ids: List[int]) -> Optional[Dict]: "name": "EpisodeSearch", "episodeIds": episode_ids } - return sonarr_request("command", method="POST", data=data) + response = sonarr_request("command", method="POST", data=data) + return wait_for_command(response['id']) + +def get_download_queue_size() -> Optional[int]: + """ + GET /api/v3/queue + Returns total number of items in the queue with the status 'downloading'. + """ + response = sonarr_request("queue?status=downloading") + total_records = response.get("totalRecords", 0) + if not isinstance(total_records, int): + total_records = 0 + logger.debug(f"Download Queue Size: {total_records}") + + return total_records def get_cutoff_unmet(page: int = 1) -> Optional[Dict]: """ diff --git a/config.py b/config.py index 1cf631f7..fd2ad61b 100644 --- a/config.py +++ b/config.py @@ -46,6 +46,27 @@ STATE_RESET_INTERVAL_HOURS = 168 print(f"Warning: Invalid STATE_RESET_INTERVAL_HOURS value, using default: {STATE_RESET_INTERVAL_HOURS}") +# Delay in seconds between checking the status of a command (default 1 second) +try: + COMMAND_WAIT_DELAY = int(os.environ.get("COMMAND_WAIT_DELAY", "1")) +except ValueError: + COMMAND_WAIT_DELAY = 1 + print(f"Warning: Invalid COMMAND_WAIT_DELAY value, using default: {COMMAND_WAIT_DELAY}") + +# Number of attempts to wait for a command to complete before giving up (default 600 attempts) +try: + COMMAND_WAIT_ATTEMPTS = int(os.environ.get("COMMAND_WAIT_ATTEMPTS", "600")) +except ValueError: + COMMAND_WAIT_ATTEMPTS = 600 + print(f"Warning: Invalid COMMAND_WAIT_ATTEMPTS value, using default: {COMMAND_WAIT_ATTEMPTS}") + +# Minimum size of the download queue before starting a hunt (default -1) +try: + MINIMUM_DOWNLOAD_QUEUE_SIZE = int(os.environ.get("MINIMUM_DOWNLOAD_QUEUE_SIZE", "-1")) +except ValueError: + MINIMUM_DOWNLOAD_QUEUE_SIZE = -1 + print(f"Warning: Invalid MINIMUM_DOWNLOAD_QUEUE_SIZE value, using default: {MINIMUM_DOWNLOAD_QUEUE_SIZE}") + # Selection Settings RANDOM_SELECTION = os.environ.get("RANDOM_SELECTION", "true").lower() == "true" MONITORED_ONLY = os.environ.get("MONITORED_ONLY", "true").lower() == "true" @@ -64,6 +85,8 @@ def log_configuration(logger): logger.info(f"Missing Content Configuration: HUNT_MISSING_SHOWS={HUNT_MISSING_SHOWS}") logger.info(f"Upgrade Configuration: HUNT_UPGRADE_EPISODES={HUNT_UPGRADE_EPISODES}") logger.info(f"State Reset Interval: {STATE_RESET_INTERVAL_HOURS} hours") + logger.info(f"Minimum Download Queue Size: {MINIMUM_DOWNLOAD_QUEUE_SIZE}") logger.info(f"MONITORED_ONLY={MONITORED_ONLY}, RANDOM_SELECTION={RANDOM_SELECTION}") logger.info(f"HUNT_MODE={HUNT_MODE}, SLEEP_DURATION={SLEEP_DURATION}s") + logger.info(f"COMMAND_WAIT_DELAY={COMMAND_WAIT_DELAY}, COMMAND_WAIT_ATTEMPTS={COMMAND_WAIT_ATTEMPTS}") logger.debug(f"API_KEY={API_KEY}") \ No newline at end of file diff --git a/main.py b/main.py index 24b08d06..636f59f0 100644 --- a/main.py +++ b/main.py @@ -7,10 +7,11 @@ import time import sys from utils.logger import logger -from config import HUNT_MODE, SLEEP_DURATION, log_configuration +from config import HUNT_MODE, SLEEP_DURATION, MINIMUM_DOWNLOAD_QUEUE_SIZE, log_configuration from missing import process_missing_episodes from upgrade import process_cutoff_upgrades from state import check_state_reset, calculate_reset_time +from api import get_download_queue_size def main_loop() -> None: """Main processing loop for Huntarr-Sonarr""" @@ -22,16 +23,23 @@ def main_loop() -> None: # Track if any processing was done in this cycle processing_done = False + + # Check if we should ignore the download queue size or if we are below the minimum queue size + download_queue_size = get_download_queue_size() + if MINIMUM_DOWNLOAD_QUEUE_SIZE < 0 or (MINIMUM_DOWNLOAD_QUEUE_SIZE >= 0 and download_queue_size <= MINIMUM_DOWNLOAD_QUEUE_SIZE): - # Process shows/episodes based on HUNT_MODE - if HUNT_MODE in ["missing", "both"]: - if process_missing_episodes(): - processing_done = True - - if HUNT_MODE in ["upgrade", "both"]: - if process_cutoff_upgrades(): - processing_done = True - + # Process shows/episodes based on HUNT_MODE + if HUNT_MODE in ["missing", "both"]: + if process_missing_episodes(): + processing_done = True + + if HUNT_MODE in ["upgrade", "both"]: + if process_cutoff_upgrades(): + processing_done = True + + else: + logger.info(f"Download queue size ({download_queue_size}) is above the minimum threshold ({MINIMUM_DOWNLOAD_QUEUE_SIZE}). Skipped processing.") + # Calculate time until the next reset calculate_reset_time() diff --git a/missing.py b/missing.py index 39d780ff..b9af8572 100644 --- a/missing.py +++ b/missing.py @@ -93,20 +93,18 @@ def process_missing_episodes() -> bool: # Refresh the series logger.info(f" - Refreshing series (ID: {series_id})...") refresh_res = refresh_series(series_id) - if not refresh_res or "id" not in refresh_res: + if not refresh_res: logger.warning(f"WARNING: Refresh command failed for {show_title}. Skipping.") - time.sleep(5) continue - logger.info(f"Refresh command accepted (ID: {refresh_res['id']}). Waiting 5s...") - time.sleep(5) + logger.info(f"Refresh command completed successfully.") # Search specifically for these missing + monitored episodes episode_ids = [ep["id"] for ep in monitored_missing_episodes] logger.info(f" - Searching for {len(episode_ids)} missing episodes in '{show_title}'...") search_res = episode_search_episodes(episode_ids) - if search_res and "id" in search_res: - logger.info(f"Search command accepted (ID: {search_res['id']}).") + if search_res: + logger.info(f"Search command completed successfully.") processing_done = True else: logger.warning(f"WARNING: EpisodeSearch failed for show '{show_title}' (ID: {series_id}).") diff --git a/upgrade.py b/upgrade.py index aac6bf0a..79e68c79 100644 --- a/upgrade.py +++ b/upgrade.py @@ -103,19 +103,17 @@ def process_cutoff_upgrades() -> bool: # Refresh the series logger.info(" - Refreshing series information...") refresh_res = refresh_series(series_id) - if not refresh_res or "id" not in refresh_res: + if not refresh_res: logger.warning("WARNING: Refresh command failed. Skipping this episode.") - time.sleep(10) continue - - logger.info(f"Refresh command accepted (ID: {refresh_res['id']}). Waiting 5s...") - time.sleep(5) + + logger.info(f"Refresh command completed successfully.") # Search for the episode (upgrade) logger.info(" - Searching for quality upgrade...") search_res = episode_search_episodes([episode_id]) - if search_res and "id" in search_res: - logger.info(f"Search command accepted (ID: {search_res['id']}).") + if search_res: + logger.info(f"Search command completed successfully.") # Mark processed save_processed_id(PROCESSED_UPGRADE_FILE, episode_id) episodes_processed += 1 @@ -123,7 +121,6 @@ def process_cutoff_upgrades() -> bool: logger.info(f"Processed {episodes_processed}/{HUNT_UPGRADE_EPISODES} upgrade episodes this cycle.") else: logger.warning(f"WARNING: Search command failed for episode ID {episode_id}.") - time.sleep(10) continue # Move to the next page if not random From db32d042ce3452e810cbe158ca6db3852ce9ebc4 Mon Sep 17 00:00:00 2001 From: Admin9705 <24727006+Admin9705@users.noreply.github.com> Date: Mon, 7 Apr 2025 08:52:50 -0400 Subject: [PATCH 7/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 76855f28..ffe3ac8d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@
-**NOTE**: This utilizes Sonarr API Version - `5`. +**NOTE**: This utilizes Sonarr API Version - `5`. Legacy name of this program: Sonarr Hunter. ## Table of Contents - [Overview](#overview) From ab4f9f1aa81460cc349f70f7c9eb871c87f3b236 Mon Sep 17 00:00:00 2001 From: Admin9705 <9705@duck.com> Date: Mon, 7 Apr 2025 12:15:51 -0400 Subject: [PATCH 8/8] suport arm --- .github/workflows/docker-image.yml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ce9f9c01..ea7c086d 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -23,11 +23,17 @@ jobs: - name: List files in directory run: ls -la - # 3) Set up Docker Buildx + # 3) Set up QEMU for multi-architecture builds + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: arm64,amd64 + + # 4) Set up Docker Buildx - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - # 4) Log in to Docker Hub + # 5) Log in to Docker Hub - name: Log in to Docker Hub if: github.event_name != 'pull_request' uses: docker/login-action@v2 @@ -35,49 +41,53 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - # 5) Extract version from tag if it's a tag push + # 6) Extract version from tag if it's a tag push - name: Extract version from tag if: startsWith(github.ref, 'refs/tags/') id: get_version run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - # 6a) Build & Push if on 'main' branch + # 7a) Build & Push if on 'main' branch - name: Build and Push (main) if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' uses: docker/build-push-action@v3 with: context: . push: true + platforms: linux/amd64,linux/arm64 tags: | huntarr/4sonarr:latest huntarr/4sonarr:${{ github.sha }} - # 6b) Build & Push if on 'dev' branch + # 7b) Build & Push if on 'dev' branch - name: Build and Push (dev) if: github.ref == 'refs/heads/dev' && github.event_name != 'pull_request' uses: docker/build-push-action@v3 with: context: . push: true + platforms: linux/amd64,linux/arm64 tags: | huntarr/4sonarr:dev huntarr/4sonarr:${{ github.sha }} - # 6c) Build & Push if it's a tag/release + # 7c) Build & Push if it's a tag/release - name: Build and Push (release) if: startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' uses: docker/build-push-action@v3 with: context: . push: true + platforms: linux/amd64,linux/arm64 tags: | huntarr/4sonarr:${{ steps.get_version.outputs.VERSION }} huntarr/4sonarr:latest - # 6d) Just build on pull requests + # 7d) Just build on pull requests - name: Build (PR) if: github.event_name == 'pull_request' uses: docker/build-push-action@v3 with: context: . push: false + platforms: linux/amd64,linux/arm64 \ No newline at end of file