Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ PlexCleaner is a .NET 10.0 CLI utility that optimizes media files for Direct Pla

The tool orchestrates external media processing tools (FFmpeg, HandBrake, MkvToolNix, MediaInfo, 7-Zip) via CLI wrappers.

## Branching, Releases, and Bot Behavior

For full rationale see [`AGENTS.md`](../AGENTS.md). Quick rules:

- `feature → develop → main`. PRs only.
- Develop accepts **squash merges only**; main accepts **merge commits only**. Don't suggest rebase-merge — it's disabled at the repo level.
- Both branches **auto-publish on push**: develop produces NBGV prereleases (`X.Y.Z-g{sha}`) tagged `develop` on Docker Hub; main produces stable releases (`X.Y.Z`) tagged `latest`.
- Dependabot targets **both** `main` and `develop` with the same ecosystems; major NuGet bumps gate on human review, everything else auto-merges via App-token-driven merge-bot.
- Every third-party GitHub Action is pinned to a full commit SHA with a `# vX.Y.Z` comment. Don't introduce `@v6` / `@main` / `@master` floating refs.
- Don't recommend `git push --force` or `--force-with-lease`; both rulesets enforce `non_fast_forward`.
- `version.json`'s `publicReleaseRefSpec` is `^refs/heads/main$` — bumping the base `version` field is the only manual versioning action.

## Documentation

User-facing documentation is organized as follows:
Expand Down
56 changes: 38 additions & 18 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,41 @@ version: 2
updates:

# main
- package-ecosystem: "nuget"
target-branch: "main"
directory: "/"
schedule:
interval: "daily"
groups:
nuget-deps:
patterns:
- "*"
- package-ecosystem: "github-actions"
target-branch: "main"
directory: "/"
schedule:
interval: "daily"
groups:
actions-deps:
patterns:
- "*"
- package-ecosystem: "nuget"
target-branch: "main"
directory: "/"
schedule:
interval: "daily"
groups:
nuget-deps:
patterns:
- "*"
- package-ecosystem: "github-actions"
target-branch: "main"
directory: "/"
schedule:
interval: "daily"
groups:
actions-deps:
patterns:
- "*"

# develop
- package-ecosystem: "nuget"
target-branch: "develop"
directory: "/"
schedule:
interval: "daily"
groups:
nuget-deps:
patterns:
- "*"
- package-ecosystem: "github-actions"
target-branch: "develop"
directory: "/"
schedule:
interval: "daily"
groups:
actions-deps:
patterns:
- "*"
2 changes: 1 addition & 1 deletion .github/workflows/build-datebadge-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:

- name: Build BYOB date badge step
if: ${{ github.ref_name == 'main' }}
uses: RubbaBoy/BYOB@v1
uses: RubbaBoy/BYOB@24f464284c1fd32028524b59607d417a2e36fee7 # v1.3.0
with:
name: lastbuild
label: "Last Build"
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/build-docker-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,28 @@ jobs:
steps:

- name: Checkout step
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup QEMU step
uses: docker/setup-qemu-action@v4
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
with:
platforms: linux/amd64,linux/arm64

- name: Setup Buildx step
uses: docker/setup-buildx-action@v4
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
with:
platforms: linux/amd64,linux/arm64

# Always login to Docker Hub, not just on push, to benefit from
# higher rate limits with a Docker subscription for pulls and cache
- name: Login to Docker Hub step
uses: docker/login-action@v4
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Docker build and push step
uses: docker/build-push-action@v7
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: ${{ inputs.push }}
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/build-executable-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ jobs:
steps:

- name: Setup .NET SDK step
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
dotnet-version: 10.x

- name: Checkout code step
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Build executable project step
run: |
Expand All @@ -46,7 +46,7 @@ jobs:
-property:PackageVersion=${{ needs.get-version.outputs.SemVer2 }}

- name: Upload matrix build artifacts step
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: publish-${{ matrix.runtime }}
path: ${{ runner.temp }}/publish
Expand All @@ -61,7 +61,7 @@ jobs:
steps:

- name: Download matrix build artifacts step
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: publish-*
merge-multiple: true
Expand All @@ -72,7 +72,7 @@ jobs:

- name: Upload build artifacts step
id: artifact-upload-step
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: executable-build
path: ${{ runner.temp }}/PlexCleaner.7z
10 changes: 6 additions & 4 deletions .github/workflows/build-release-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,22 @@ jobs:
steps:

- name: Checkout code step
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Download executable build artifacts step
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
artifact-ids: ${{ needs.build-executable.outputs.artifact-id }}
path: ./Publish

- name: Create GitHub release step
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
generate_release_notes: true
tag_name: ${{ needs.get-version.outputs.SemVer2 }}
target_commitish: ${{ github.sha }}
prerelease: ${{ github.ref_name != 'main' }}
generate_release_notes: true
fail_on_unmatched_files: true
files: |
LICENSE
README.md
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/get-version-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ jobs:
steps:

- name: Setup .NET SDK step
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
dotnet-version: 10.x

- name: Checkout code step
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Run Nerdbank.GitVersioning tool step
id: nbgv
uses: dotnet/nbgv@master
uses: dotnet/nbgv@3cf2d96c2aa00675081b59f401356ac1fb81092f # v0.5.1
51 changes: 42 additions & 9 deletions .github/workflows/merge-bot-pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Merge bot pull request action

on:
"on":
pull_request:
Comment thread
ptr727 marked this conversation as resolved.
types: [opened, reopened, synchronize]

Expand All @@ -13,29 +13,62 @@ jobs:
merge-dependabot:
name: Merge dependabot pull request job
runs-on: ubuntu-latest
# To prevent abuse, the PR must come from Dependabot and the PR must originate from this repository.
# Restrict to dependabot PRs that originate from this repository, not a
# fork. Check the PR author rather than the event actor so maintainer
# repair commits on Dependabot branches can still auto-merge after CI
# passes.
if: >-
github.actor == 'dependabot[bot]' &&
github.event.pull_request.user.login == 'dependabot[bot]' &&
github.event.pull_request.head.repo.full_name == github.repository
permissions:
contents: write
pull-requests: write

steps:

- name: Generate GitHub App token step
# Use an App token (not GITHUB_TOKEN) so the resulting merge push is
# committed by the App and fires downstream workflows on develop/main.
# Pushes from GITHUB_TOKEN are blocked from triggering further workflow
# runs by GitHub's recursion guard, which would silently skip
# publish-release.yml and publish-periodic-docker-release.yml on the
# merge commit and prevent develop's auto-prerelease/Docker rebuild.
id: app-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
client-id: ${{ secrets.CODEGEN_APP_CLIENT_ID }}
private-key: ${{ secrets.CODEGEN_APP_PRIVATE_KEY }}

- name: Get dependabot metadata step
id: metadata
uses: dependabot/fetch-metadata@v3
uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"

# Merge any non-NuGet update, e.g. GitHub Actions often updates v1 to v2.
# Merge NuGet only for non-major updates, e.g. major updates may build but break functionality.
# Skip semver-major NuGet bumps: they often build cleanly but break
# runtime behavior, so they should land via human review. GitHub Actions
# majors auto-merge because the workflow execution itself validates them.
#
# Merge method must match the base branch's ruleset:
# develop -> squash only (linear history)
# main -> merge commits only (preserves develop ancestry)
# A mismatch fails enablePullRequestAutoMerge with
# "Merge method ... is not allowed on this repository".
- name: Merge pull request step
if: >-
(steps.metadata.outputs.package-ecosystem != 'nuget') ||
(steps.metadata.outputs.update-type != 'version-update:semver-major')
run: gh pr merge --auto --squash "$PR_URL"
run: |
set -euo pipefail
case "${{ github.event.pull_request.base.ref }}" in
develop) method=--squash ;;
main) method=--merge ;;
*)
echo "::error::Unsupported base branch: ${{ github.event.pull_request.base.ref }}"
exit 1
;;
esac
gh pr merge --auto "$method" "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
Loading
Loading