Skip to content

Merge pull request #18 from nullable-eth/dependabot/github_actions/ac… #15

Merge pull request #18 from nullable-eth/dependabot/github_actions/ac…

Merge pull request #18 from nullable-eth/dependabot/github_actions/ac… #15

Workflow file for this run

name: Create Release
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
push:
branches:
- main
paths-ignore:
- 'README*.md'
- 'LICENSE'
- '.gitignore'
- 'IMPLEMENTATION_PLAN.md'
jobs:
check-changes:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.changes.outputs.should_release }}
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Check for significant changes
id: changes
run: |
# Get the last release tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
echo "Last tag: ${LAST_TAG:-'(none)'}"
# Check if there are changes in source code since last release
if [[ -z "$LAST_TAG" ]]; then
# No previous tags, this is the first release
echo "No previous tags found - first release"
echo "should_release=true" >> $GITHUB_OUTPUT
elif git diff --quiet $LAST_TAG HEAD -- '*.go' 'go.mod' 'go.sum' 'Dockerfile' '.github/workflows/' 'internal/' 'cmd/' 'pkg/'; then
echo "No significant changes detected"
echo "should_release=false" >> $GITHUB_OUTPUT
else
echo "Significant changes detected"
echo "should_release=true" >> $GITHUB_OUTPUT
fi
- name: Calculate next version
id: version
if: steps.changes.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch'
run: |
# Get the last release tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
echo "Last tag: ${LAST_TAG:-'(none)'}"
# Handle first release vs. subsequent releases
if [[ -z "$LAST_TAG" ]]; then
# First release - start from v0.0.0
MAJOR=0
MINOR=1
PATCH=0
echo "First release - starting from v0.1.0"
else
# Remove 'v' prefix and split version
VERSION_NUMBER=${LAST_TAG#v}
IFS='.' read -r -a VERSION_PARTS <<< "$VERSION_NUMBER"
MAJOR=${VERSION_PARTS[0]:-0}
MINOR=${VERSION_PARTS[1]:-0}
PATCH=${VERSION_PARTS[2]:-0}
fi
# Determine release type
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
RELEASE_TYPE="${{ github.event.inputs.release_type }}"
else
# Auto-determine based on commit messages since last release
if [[ -z "$LAST_TAG" ]]; then
# First release - check all commits
COMMITS=$(git log --oneline)
else
# Subsequent release - check commits since last tag
COMMITS=$(git log $LAST_TAG..HEAD --oneline)
fi
if echo "$COMMITS" | grep -qE "(BREAKING CHANGE|!:)"; then
RELEASE_TYPE="major"
elif echo "$COMMITS" | grep -qE "(feat:|feature:)"; then
RELEASE_TYPE="minor"
else
RELEASE_TYPE="patch"
fi
fi
echo "Release type: $RELEASE_TYPE"
# Increment version based on release type
case $RELEASE_TYPE in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
esac
NEW_VERSION="v${MAJOR}.${MINOR}.${PATCH}"
echo "New version: $NEW_VERSION"
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.23'
- name: Cache Go modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Download dependencies
run: go mod download
- name: Run tests
run: go test -v ./...
- name: Run go vet
run: go vet ./...
- name: Run go fmt check
run: |
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
echo "The following files need to be formatted:"
gofmt -s -l .
exit 1
fi
build:
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.23'
- name: Build application
run: |
# Set build variables
VERSION="${{ needs.check-changes.outputs.version }}"
COMMIT="${{ github.sha }}"
BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
LDFLAGS="-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${BUILD_DATE}"
# Build for multiple architectures
GOOS=linux GOARCH=amd64 go build -ldflags "${LDFLAGS}" -o syncarr-linux-amd64 ./cmd/syncarr
GOOS=linux GOARCH=arm64 go build -ldflags "${LDFLAGS}" -o syncarr-linux-arm64 ./cmd/syncarr
GOOS=windows GOARCH=amd64 go build -ldflags "${LDFLAGS}" -o syncarr-windows-amd64.exe ./cmd/syncarr
GOOS=darwin GOARCH=amd64 go build -ldflags "${LDFLAGS}" -o syncarr-darwin-amd64 ./cmd/syncarr
GOOS=darwin GOARCH=arm64 go build -ldflags "${LDFLAGS}" -o syncarr-darwin-arm64 ./cmd/syncarr
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: syncarr-binaries
path: syncarr-*
create-release:
needs: [check-changes, test, build]
if: needs.check-changes.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Download build artifacts
uses: actions/download-artifact@v5
with:
name: syncarr-binaries
- name: Generate changelog
id: changelog
run: |
# Get the last release tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [[ -n "$LAST_TAG" ]]; then
echo "## What's Changed" > changelog.md
echo "" >> changelog.md
# Get commits since last release
git log $LAST_TAG..HEAD --pretty=format:"- %s (%h)" --reverse >> changelog.md
else
echo "## 🎉 Initial Release of SyncArr" > changelog.md
echo "" >> changelog.md
echo "SyncArr synchronizes labeled movies and TV shows between source and destination Plex Media Servers." >> changelog.md
echo "" >> changelog.md
echo "### ✨ Features" >> changelog.md
echo "- 🏷️ Label-based synchronization between Plex servers" >> changelog.md
echo "- 🔄 Bidirectional watched state synchronization" >> changelog.md
echo "- 📁 Secure SSH/SFTP file transfers with key-based authentication" >> changelog.md
echo "- 🔄 Incremental sync with change detection" >> changelog.md
echo "- 🎯 Content filtering by patterns, size, and library rules" >> changelog.md
echo "- 🐳 Docker container with complete configuration via environment variables" >> changelog.md
echo "- 📊 Comprehensive structured logging" >> changelog.md
echo "- ⚡ Force full sync option for resolving inconsistencies" >> changelog.md
echo "- 🔧 Flexible deployment (one-shot or continuous modes)" >> changelog.md
echo "" >> changelog.md
echo "### 🚀 Getting Started" >> changelog.md
echo "1. Set up SSH key-based authentication between servers" >> changelog.md
echo "2. Configure environment variables for source/destination Plex servers" >> changelog.md
echo "3. Add labels to media items you want to sync" >> changelog.md
echo "4. Deploy using Docker Compose" >> changelog.md
fi
echo "" >> changelog.md
echo "### 🐳 Docker Images" >> changelog.md
echo "" >> changelog.md
echo "**Multi-architecture support:** \`linux/amd64\`, \`linux/arm64\`" >> changelog.md
echo "" >> changelog.md
echo '```bash' >> changelog.md
echo "# Latest release" >> changelog.md
echo "docker pull ghcr.io/${{ github.repository_owner }}/syncarr:${{ needs.check-changes.outputs.version }}" >> changelog.md
echo "" >> changelog.md
echo "# Always latest" >> changelog.md
echo "docker pull ghcr.io/${{ github.repository_owner }}/syncarr:latest" >> changelog.md
echo '```' >> changelog.md
echo "" >> changelog.md
echo "### 📥 Binary Downloads" >> changelog.md
echo "" >> changelog.md
echo "Pre-compiled binaries are available for multiple platforms in the release assets below." >> changelog.md
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.check-changes.outputs.version }}
name: Release ${{ needs.check-changes.outputs.version }}
body_path: changelog.md
files: |
syncarr-linux-amd64
syncarr-linux-arm64
syncarr-windows-amd64.exe
syncarr-darwin-amd64
syncarr-darwin-arm64
draft: false
prerelease: false
generate_release_notes: true
publish-docker:
needs: [check-changes, create-release]
if: needs.check-changes.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ needs.check-changes.outputs.version }}
type=raw,value=latest
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ needs.check-changes.outputs.version }}
COMMIT=${{ github.sha }}
BUILD_DATE=${{ github.event.head_commit.timestamp }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate Docker summary
run: |
echo "## 🐳 Docker Image Published" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version:** ${{ needs.check-changes.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Registry:** ghcr.io" >> $GITHUB_STEP_SUMMARY
echo "**Platforms:** linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Tags:**" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "ghcr.io/${{ github.repository }}:${{ needs.check-changes.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "ghcr.io/${{ github.repository }}:latest" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "docker pull ghcr.io/${{ github.repository }}:${{ needs.check-changes.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY