Build and Push Gunbot Core Docker Image #181
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Push Gunbot Core Docker Image | |
| on: | |
| schedule: | |
| # Run daily at UTC 06:00 (KST 15:00) | |
| - cron: "0 6 * * *" | |
| workflow_dispatch: | |
| # Allow manual execution | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - "Dockerfile" | |
| - ".github/workflows/docker-build-gunbot-core.yml" | |
| - ".github/scripts/**" | |
| # Least-privilege but enough to create releases and read repo | |
| permissions: | |
| contents: write | |
| env: | |
| DOCKER_IMAGE: magicdude4eva/gunbot-colorised | |
| GUNBOT_DOWNLOAD_URL: https://www.gunbot.com/downloads/ | |
| concurrency: | |
| group: gunbot-docker-build | |
| cancel-in-progress: false | |
| jobs: | |
| build-and-push: | |
| runs-on: ubuntu-latest | |
| steps: | |
| # ------------------------------------------------------------ | |
| # Repo | |
| # ------------------------------------------------------------ | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # allow committing CHANGELOG/README updates | |
| # ------------------------------------------------------------ | |
| # Detect latest Gunbot version (used as Docker tag) | |
| # ------------------------------------------------------------ | |
| - name: Extract Gunbot version from website | |
| id: version | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| echo "Fetching Gunbot version from download page..." | |
| UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" | |
| html_content=$(curl -sS --retry 3 --retry-delay 2 --user-agent "$UA" "$GUNBOT_DOWNLOAD_URL") | |
| # Extract the version from the Linux download link text | |
| version=$(echo "$html_content" | grep -oP 'href="https://gunthy\.org/downloads/gunthy_linux\.zip".*?\(v\K[0-9]+\.[0-9]+\.[0-9]+' | head -1) | |
| if [ -z "$version" ]; then | |
| echo "Warning: Could not extract version from download page, using fallback" | |
| version="30.5.9" | |
| else | |
| version="v$version" | |
| fi | |
| echo "Detected Gunbot version: $version" | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| # ------------------------------------------------------------ | |
| # Skip build if tag already exists on Docker Hub | |
| # ------------------------------------------------------------ | |
| - name: Check if version already exists on Docker Hub | |
| id: check | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| version="${{ steps.version.outputs.version }}" | |
| echo "Checking if Docker tag exists: $version" | |
| # Public repo check via Docker Hub API | |
| resp=$(curl -sS --retry 3 --retry-delay 2 "https://hub.docker.com/v2/repositories/${{ env.DOCKER_IMAGE }}/tags/${version}/" || true) | |
| if echo "$resp" | grep -q '"name"'; then | |
| echo "Version $version already exists on Docker Hub. Skipping build." | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Version $version not found on Docker Hub. Proceeding." | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| # ------------------------------------------------------------ | |
| # Telegram → changelog (tight window; only if building) | |
| # ------------------------------------------------------------ | |
| - name: Setup Python and jq | |
| if: steps.check.outputs.exists == 'false' | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install telethon | |
| sudo apt-get update -y | |
| sudo apt-get install -y jq | |
| - name: Fetch releases from Telegram (7 days / 100 msgs) | |
| if: steps.check.outputs.exists == 'false' | |
| id: tg | |
| env: | |
| TELEGRAM_API_ID: ${{ secrets.TELEGRAM_API_ID }} | |
| TELEGRAM_API_HASH: ${{ secrets.TELEGRAM_API_HASH }} | |
| TELEGRAM_SESSION: ${{ secrets.TELEGRAM_SESSION }} | |
| TG_CHANNEL: ${{ secrets.TG_CHANNEL }} # numeric private channel id | |
| SINCE_DAYS: "7" | |
| MAX_MESSAGES: "100" | |
| run: | | |
| python .github/scripts/fetch_telegram_releases.py > releases.json | |
| echo "count_total=$(jq '.releases | length' releases.json)" >> "$GITHUB_OUTPUT" | |
| jq -r '.releases[0].version // empty' releases.json > latest_version.txt || true | |
| - name: Select Telegram block for current version | |
| if: steps.check.outputs.exists == 'false' | |
| id: tsel | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| target="${{ steps.version.outputs.version }}" | |
| if [ ! -s releases.json ]; then | |
| echo "count=0" >> "$GITHUB_OUTPUT"; exit 0 | |
| fi | |
| jq --arg v "$target" '{releases: [.releases[] | select(.version == $v)]}' releases.json > releases_target.json | |
| echo "count=$(jq '.releases | length' releases_target.json)" >> "$GITHUB_OUTPUT" | |
| - name: Summarize current version (no AI) | |
| if: steps.check.outputs.exists == 'false' && steps.tsel.outputs.count != '0' | |
| id: summarize | |
| shell: bash | |
| run: | | |
| python .github/scripts/summarize_releases_noai.py < releases_target.json > CHANGELOG_SNIPPET.md | |
| # Strip leading "### vX.Y.Z" for the release body; keep full snippet for CHANGELOG.md | |
| tail -n +2 CHANGELOG_SNIPPET.md > RELEASE_NOTES.md | |
| { | |
| echo 'changes<<EOF' | |
| cat RELEASE_NOTES.md | |
| echo 'EOF' | |
| } >> "$GITHUB_OUTPUT" | |
| # ------------------------------------------------------------ | |
| # Build & push Docker image (only when new) | |
| # ------------------------------------------------------------ | |
| - name: Set up Docker Buildx | |
| if: steps.check.outputs.exists == 'false' | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Docker Hub | |
| if: steps.check.outputs.exists == 'false' | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Build and push Docker image | |
| if: steps.check.outputs.exists == 'false' | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64 | |
| push: true | |
| tags: | | |
| ${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.version }} | |
| ${{ env.DOCKER_IMAGE }}:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| labels: | | |
| org.opencontainers.image.title=Gunbot Colorised Docker Edition for Synology NAS | |
| org.opencontainers.image.version=${{ steps.version.outputs.version }} | |
| org.opencontainers.image.source=https://github.com/${{ github.repository }} | |
| # ------------------------------------------------------------ | |
| # Prepend to CHANGELOG.md and bump README (only if we had notes) | |
| # ------------------------------------------------------------ | |
| - name: Update CHANGELOG.md (prepend) and README | |
| if: steps.check.outputs.exists == 'false' && steps.tsel.outputs.count != '0' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| tg_ver="${{ steps.version.outputs.version }}" | |
| touch CHANGELOG.md | |
| if [ -n "$tg_ver" ] && ! grep -q "^### ${tg_ver}$" CHANGELOG.md; then | |
| echo "Prepending ${tg_ver} to CHANGELOG.md" | |
| { | |
| cat CHANGELOG_SNIPPET.md | |
| echo | |
| cat CHANGELOG.md | |
| } > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md | |
| else | |
| echo "No new changelog section to add." | |
| fi | |
| if [ -n "$tg_ver" ] && grep -q '^✅ Compatible with Gunbot version:' README.md; then | |
| sed -i -E "s#^(✅ Compatible with Gunbot version: ).*#\1Gunbot ${tg_ver}#g" README.md | |
| fi | |
| git diff --quiet -- CHANGELOG.md README.md || \ | |
| (git config user.name github-actions[bot]; git config user.email 41898282+github-actions[bot]@users.noreply.github.com; \ | |
| git add CHANGELOG.md README.md && git commit -m "docs: update changelog and bump README" && git push) | |
| # ------------------------------------------------------------ | |
| # Release with inline notes | |
| # ------------------------------------------------------------ | |
| - name: Create GitHub Release | |
| if: steps.check.outputs.exists == 'false' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| name: Gunbot ${{ steps.version.outputs.version }} | |
| generate_release_notes: true | |
| body: | | |
| ## Gunbot Docker Image ${{ steps.version.outputs.version }} | |
| ${{ steps.summarize.outputs.changes }} | |
| ### 📦 Docker Tags | |
| - ${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.version }} | |
| - ${{ env.DOCKER_IMAGE }}:latest | |
| ### 🔗 Links | |
| - Docker Hub: https://hub.docker.com/r/${{ env.DOCKER_IMAGE }} | |
| - Documentation: https://github.com/${{ github.repository }}/blob/main/README.md | |
| - Purchase Gunbot: https://gunbot.at/ | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Update Docker Hub README | |
| if: steps.check.outputs.exists == 'false' # only when you actually pushed a new tag | |
| uses: peter-evans/dockerhub-description@v5 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} # use a Docker Hub access token | |
| repository: magicdude4eva/gunbot-colorised | |
| readme-filepath: ./README.md # default; change if needed | |
| short-description: ${{ github.event.repository.description }} | |
| enable-url-completion: true # rewrites relative links to absolute | |
| - name: Summary | |
| if: steps.check.outputs.exists == 'false' | |
| run: | | |
| echo "Successfully built and pushed Gunbot ${{ steps.version.outputs.version }} to Docker Hub" | |
| echo "Tags:" | |
| echo "- ${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.version }}" | |
| echo "- ${{ env.DOCKER_IMAGE }}:latest" |