Merge pull request #18 from nullable-eth/dependabot/github_actions/ac… #15
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: 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 |