Skip to content

Commit 066fb96

Browse files
committed
!: Initial release with file syncing
1 parent 96eaa83 commit 066fb96

File tree

25 files changed

+6893
-12
lines changed

25 files changed

+6893
-12
lines changed

.github/dependabot.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
version: 2
2+
updates:
3+
# Enable version updates for Go modules
4+
- package-ecosystem: "gomod"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
day: "monday"
9+
time: "09:00"
10+
reviewers:
11+
- "nullable-eth"
12+
assignees:
13+
- "nullable-eth"
14+
commit-message:
15+
prefix: "deps"
16+
prefix-development: "deps(dev)"
17+
include: "scope"
18+
open-pull-requests-limit: 5
19+
labels:
20+
- "dependencies"
21+
- "go"
22+
23+
# Enable version updates for GitHub Actions
24+
- package-ecosystem: "github-actions"
25+
directory: "/"
26+
schedule:
27+
interval: "weekly"
28+
day: "monday"
29+
time: "09:00"
30+
reviewers:
31+
- "nullable-eth"
32+
assignees:
33+
- "nullable-eth"
34+
commit-message:
35+
prefix: "ci"
36+
include: "scope"
37+
open-pull-requests-limit: 5
38+
labels:
39+
- "dependencies"
40+
- "github-actions"
41+
42+
# Enable version updates for Docker
43+
- package-ecosystem: "docker"
44+
directory: "/"
45+
schedule:
46+
interval: "weekly"
47+
day: "monday"
48+
time: "09:00"
49+
reviewers:
50+
- "nullable-eth"
51+
assignees:
52+
- "nullable-eth"
53+
commit-message:
54+
prefix: "docker"
55+
include: "scope"
56+
open-pull-requests-limit: 3
57+
labels:
58+
- "dependencies"
59+
- "docker"

.github/workflows/release.yml

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
name: Create Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
release_type:
7+
description: 'Release type'
8+
required: true
9+
default: 'patch'
10+
type: choice
11+
options:
12+
- patch
13+
- minor
14+
- major
15+
push:
16+
branches:
17+
- main
18+
paths-ignore:
19+
- 'README*.md'
20+
- 'LICENSE'
21+
- '.gitignore'
22+
- 'IMPLEMENTATION_PLAN.md'
23+
24+
jobs:
25+
check-changes:
26+
runs-on: ubuntu-latest
27+
outputs:
28+
should_release: ${{ steps.changes.outputs.should_release }}
29+
version: ${{ steps.version.outputs.version }}
30+
steps:
31+
- name: Checkout repository
32+
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 0
35+
36+
- name: Check for significant changes
37+
id: changes
38+
run: |
39+
# Get the last release tag
40+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
41+
echo "Last tag: ${LAST_TAG:-'(none)'}"
42+
43+
# Check if there are changes in source code since last release
44+
if [[ -z "$LAST_TAG" ]]; then
45+
# No previous tags, this is the first release
46+
echo "No previous tags found - first release"
47+
echo "should_release=true" >> $GITHUB_OUTPUT
48+
elif git diff --quiet $LAST_TAG HEAD -- '*.go' 'go.mod' 'go.sum' 'Dockerfile' '.github/workflows/' 'internal/' 'cmd/' 'pkg/'; then
49+
echo "No significant changes detected"
50+
echo "should_release=false" >> $GITHUB_OUTPUT
51+
else
52+
echo "Significant changes detected"
53+
echo "should_release=true" >> $GITHUB_OUTPUT
54+
fi
55+
56+
- name: Calculate next version
57+
id: version
58+
if: steps.changes.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch'
59+
run: |
60+
# Get the last release tag
61+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
62+
echo "Last tag: ${LAST_TAG:-'(none)'}"
63+
64+
# Handle first release vs. subsequent releases
65+
if [[ -z "$LAST_TAG" ]]; then
66+
# First release - start from v0.0.0
67+
MAJOR=0
68+
MINOR=1
69+
PATCH=0
70+
echo "First release - starting from v0.1.0"
71+
else
72+
# Remove 'v' prefix and split version
73+
VERSION_NUMBER=${LAST_TAG#v}
74+
IFS='.' read -r -a VERSION_PARTS <<< "$VERSION_NUMBER"
75+
76+
MAJOR=${VERSION_PARTS[0]:-0}
77+
MINOR=${VERSION_PARTS[1]:-0}
78+
PATCH=${VERSION_PARTS[2]:-0}
79+
fi
80+
81+
# Determine release type
82+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
83+
RELEASE_TYPE="${{ github.event.inputs.release_type }}"
84+
else
85+
# Auto-determine based on commit messages since last release
86+
if [[ -z "$LAST_TAG" ]]; then
87+
# First release - check all commits
88+
COMMITS=$(git log --oneline)
89+
else
90+
# Subsequent release - check commits since last tag
91+
COMMITS=$(git log $LAST_TAG..HEAD --oneline)
92+
fi
93+
94+
if echo "$COMMITS" | grep -qE "(BREAKING CHANGE|!:)"; then
95+
RELEASE_TYPE="major"
96+
elif echo "$COMMITS" | grep -qE "(feat:|feature:)"; then
97+
RELEASE_TYPE="minor"
98+
else
99+
RELEASE_TYPE="patch"
100+
fi
101+
fi
102+
103+
echo "Release type: $RELEASE_TYPE"
104+
105+
# Increment version based on release type
106+
case $RELEASE_TYPE in
107+
major)
108+
MAJOR=$((MAJOR + 1))
109+
MINOR=0
110+
PATCH=0
111+
;;
112+
minor)
113+
MINOR=$((MINOR + 1))
114+
PATCH=0
115+
;;
116+
patch)
117+
PATCH=$((PATCH + 1))
118+
;;
119+
esac
120+
121+
NEW_VERSION="v${MAJOR}.${MINOR}.${PATCH}"
122+
echo "New version: $NEW_VERSION"
123+
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
124+
125+
test:
126+
runs-on: ubuntu-latest
127+
steps:
128+
- name: Checkout repository
129+
uses: actions/checkout@v4
130+
131+
- name: Set up Go
132+
uses: actions/setup-go@v4
133+
with:
134+
go-version: '1.23'
135+
136+
- name: Cache Go modules
137+
uses: actions/cache@v3
138+
with:
139+
path: ~/go/pkg/mod
140+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
141+
restore-keys: |
142+
${{ runner.os }}-go-
143+
144+
- name: Download dependencies
145+
run: go mod download
146+
147+
- name: Run tests
148+
run: go test -v ./...
149+
150+
- name: Run go vet
151+
run: go vet ./...
152+
153+
- name: Run go fmt check
154+
run: |
155+
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
156+
echo "The following files need to be formatted:"
157+
gofmt -s -l .
158+
exit 1
159+
fi
160+
161+
build:
162+
needs: test
163+
runs-on: ubuntu-latest
164+
steps:
165+
- name: Checkout repository
166+
uses: actions/checkout@v4
167+
168+
- name: Set up Go
169+
uses: actions/setup-go@v4
170+
with:
171+
go-version: '1.23'
172+
173+
- name: Build application
174+
run: |
175+
# Build for multiple architectures
176+
GOOS=linux GOARCH=amd64 go build -o syncarr-linux-amd64 ./cmd/syncarr
177+
GOOS=linux GOARCH=arm64 go build -o syncarr-linux-arm64 ./cmd/syncarr
178+
GOOS=windows GOARCH=amd64 go build -o syncarr-windows-amd64.exe ./cmd/syncarr
179+
GOOS=darwin GOARCH=amd64 go build -o syncarr-darwin-amd64 ./cmd/syncarr
180+
GOOS=darwin GOARCH=arm64 go build -o syncarr-darwin-arm64 ./cmd/syncarr
181+
182+
- name: Upload build artifacts
183+
uses: actions/upload-artifact@v4
184+
with:
185+
name: syncarr-binaries
186+
path: syncarr-*
187+
188+
create-release:
189+
needs: [check-changes, test, build]
190+
if: needs.check-changes.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch'
191+
runs-on: ubuntu-latest
192+
permissions:
193+
contents: write
194+
steps:
195+
- name: Checkout repository
196+
uses: actions/checkout@v4
197+
with:
198+
fetch-depth: 0
199+
200+
- name: Download build artifacts
201+
uses: actions/download-artifact@v4
202+
with:
203+
name: syncarr-binaries
204+
205+
- name: Generate changelog
206+
id: changelog
207+
run: |
208+
# Get the last release tag
209+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
210+
211+
if [[ -n "$LAST_TAG" ]]; then
212+
echo "## What's Changed" > changelog.md
213+
echo "" >> changelog.md
214+
215+
# Get commits since last release
216+
git log $LAST_TAG..HEAD --pretty=format:"- %s (%h)" --reverse >> changelog.md
217+
else
218+
echo "## 🎉 Initial Release of SyncArr" > changelog.md
219+
echo "" >> changelog.md
220+
echo "SyncArr synchronizes labeled movies and TV shows between source and destination Plex Media Servers." >> changelog.md
221+
echo "" >> changelog.md
222+
echo "### ✨ Features" >> changelog.md
223+
echo "- 🏷️ Label-based synchronization between Plex servers" >> changelog.md
224+
echo "- 🔄 Bidirectional watched state synchronization" >> changelog.md
225+
echo "- 📁 Secure SSH/SFTP file transfers with key-based authentication" >> changelog.md
226+
echo "- 🔄 Incremental sync with change detection" >> changelog.md
227+
echo "- 🎯 Content filtering by patterns, size, and library rules" >> changelog.md
228+
echo "- 🐳 Docker container with complete configuration via environment variables" >> changelog.md
229+
echo "- 📊 Comprehensive structured logging" >> changelog.md
230+
echo "- ⚡ Force full sync option for resolving inconsistencies" >> changelog.md
231+
echo "- 🔧 Flexible deployment (one-shot or continuous modes)" >> changelog.md
232+
echo "" >> changelog.md
233+
echo "### 🚀 Getting Started" >> changelog.md
234+
echo "1. Set up SSH key-based authentication between servers" >> changelog.md
235+
echo "2. Configure environment variables for source/destination Plex servers" >> changelog.md
236+
echo "3. Add labels to media items you want to sync" >> changelog.md
237+
echo "4. Deploy using Docker Compose" >> changelog.md
238+
fi
239+
240+
echo "" >> changelog.md
241+
echo "### 🐳 Docker Images" >> changelog.md
242+
echo "" >> changelog.md
243+
echo "**Multi-architecture support:** \`linux/amd64\`, \`linux/arm64\`" >> changelog.md
244+
echo "" >> changelog.md
245+
echo '```bash' >> changelog.md
246+
echo "# Latest release" >> changelog.md
247+
echo "docker pull ghcr.io/${{ github.repository_owner }}/syncarr:${{ needs.check-changes.outputs.version }}" >> changelog.md
248+
echo "" >> changelog.md
249+
echo "# Always latest" >> changelog.md
250+
echo "docker pull ghcr.io/${{ github.repository_owner }}/syncarr:latest" >> changelog.md
251+
echo '```' >> changelog.md
252+
echo "" >> changelog.md
253+
echo "### 📥 Binary Downloads" >> changelog.md
254+
echo "" >> changelog.md
255+
echo "Pre-compiled binaries are available for multiple platforms in the release assets below." >> changelog.md
256+
257+
- name: Create Release
258+
uses: softprops/action-gh-release@v1
259+
with:
260+
tag_name: ${{ needs.check-changes.outputs.version }}
261+
name: Release ${{ needs.check-changes.outputs.version }}
262+
body_path: changelog.md
263+
files: |
264+
syncarr-linux-amd64
265+
syncarr-linux-arm64
266+
syncarr-windows-amd64.exe
267+
syncarr-darwin-amd64
268+
syncarr-darwin-arm64
269+
draft: false
270+
prerelease: false
271+
generate_release_notes: true
272+
273+
publish-docker:
274+
needs: [check-changes, create-release]
275+
if: needs.check-changes.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch'
276+
runs-on: ubuntu-latest
277+
permissions:
278+
contents: read
279+
packages: write
280+
281+
steps:
282+
- name: Checkout repository
283+
uses: actions/checkout@v4
284+
285+
- name: Set up Docker Buildx
286+
uses: docker/setup-buildx-action@v3
287+
288+
- name: Log in to Container Registry
289+
uses: docker/login-action@v3
290+
with:
291+
registry: ghcr.io
292+
username: ${{ github.actor }}
293+
password: ${{ secrets.GITHUB_TOKEN }}
294+
295+
- name: Extract metadata
296+
id: meta
297+
uses: docker/metadata-action@v5
298+
with:
299+
images: ghcr.io/${{ github.repository }}
300+
tags: |
301+
type=raw,value=${{ needs.check-changes.outputs.version }}
302+
type=raw,value=latest
303+
304+
- name: Build and push Docker image
305+
uses: docker/build-push-action@v5
306+
with:
307+
context: .
308+
file: ./Dockerfile
309+
platforms: linux/amd64,linux/arm64
310+
push: true
311+
tags: ${{ steps.meta.outputs.tags }}
312+
labels: ${{ steps.meta.outputs.labels }}
313+
cache-from: type=gha
314+
cache-to: type=gha,mode=max
315+
316+
- name: Generate Docker summary
317+
run: |
318+
echo "## 🐳 Docker Image Published" >> $GITHUB_STEP_SUMMARY
319+
echo "" >> $GITHUB_STEP_SUMMARY
320+
echo "**Version:** ${{ needs.check-changes.outputs.version }}" >> $GITHUB_STEP_SUMMARY
321+
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
322+
echo "" >> $GITHUB_STEP_SUMMARY
323+
echo "**Registry:** ghcr.io" >> $GITHUB_STEP_SUMMARY
324+
echo "**Platforms:** linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY
325+
echo "" >> $GITHUB_STEP_SUMMARY
326+
echo "**Tags:**" >> $GITHUB_STEP_SUMMARY
327+
echo '```' >> $GITHUB_STEP_SUMMARY
328+
echo "ghcr.io/${{ github.repository }}:${{ needs.check-changes.outputs.version }}" >> $GITHUB_STEP_SUMMARY
329+
echo "ghcr.io/${{ github.repository }}:latest" >> $GITHUB_STEP_SUMMARY
330+
echo '```' >> $GITHUB_STEP_SUMMARY
331+
echo "" >> $GITHUB_STEP_SUMMARY
332+
echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY
333+
echo '```bash' >> $GITHUB_STEP_SUMMARY
334+
echo "docker pull ghcr.io/${{ github.repository }}:${{ needs.check-changes.outputs.version }}" >> $GITHUB_STEP_SUMMARY
335+
echo '```' >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)