diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml new file mode 100644 index 0000000..22a1524 --- /dev/null +++ b/.github/workflows/auto-tag.yml @@ -0,0 +1,67 @@ +name: Auto-tag release + +# Runs on every push to main. Reads the version from synology/INFO and creates +# a semver git tag if one does not already exist for that version. The release +# workflow (release.yml) picks up the new tag and publishes the Docker image +# and GitHub Release automatically. +# +# The version in synology/INFO follows the format "MAJOR.MINOR.PATCH-N" (e.g. +# "2.1.1-1"). Only the semver portion (MAJOR.MINOR.PATCH) is used as the tag. +# +# Workflow: bump the version in synology/INFO and CHANGELOG.md → open PR → +# merge to main → this workflow fires → release.yml publishes. + +on: + push: + branches: [main] + # Only consider version-carrying files. Documentation, CI workflow + # changes, and asset-only commits never bump the version and do not + # need to trigger a release check. + paths: + - "synology/INFO" + - "CHANGELOG.md" + - "backup/**" + - "docker/**" + - "tests/**" + - "webserver.py" + +permissions: + contents: write # required to push the new tag + +jobs: + tag: + name: Create release tag + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + + - name: Read version and tag if new + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + # Extract semver from synology/INFO: version="2.1.1-1" -> 2.1.1 + raw=$(grep '^version=' synology/INFO | sed 's/version="//;s/".*//') + semver="${raw%-*}" + + if ! [[ "$semver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Unexpected version format: $raw — skipping tag creation." + exit 0 + fi + + tag="v${semver}" + + if git ls-remote --tags origin "refs/tags/${tag}" | grep -q "${tag}"; then + echo "Tag ${tag} already exists — nothing to do." + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag "${tag}" -m "Release ${tag}" + git push origin "${tag}" + echo "Created and pushed tag ${tag}." diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5835f74..6970b5d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,9 +14,9 @@ jobs: name: ShellCheck runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Run ShellCheck - uses: ludeeus/action-shellcheck@master + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 with: scandir: "." severity: warning @@ -27,9 +27,9 @@ jobs: name: Hadolint (Dockerfile) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Run hadolint - uses: hadolint/hadolint-action@v3.3.0 + uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0 with: dockerfile: docker/Dockerfile config: .hadolint.yaml @@ -39,7 +39,7 @@ jobs: name: Bats unit tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install bats run: sudo apt-get update && sudo apt-get install -y bats jq - name: Run tests @@ -49,7 +49,7 @@ jobs: name: Python unit tests (webserver) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Run tests run: python3 -m unittest discover -s tests -p 'test_*.py' -v @@ -57,13 +57,13 @@ jobs: name: Docker build smoke runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up QEMU - uses: docker/setup-qemu-action@v4 + uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # v4.3.0 - name: Set up Buildx - uses: docker/setup-buildx-action@v4 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 - name: Build multi-arch image (no push) - uses: docker/build-push-action@v7 + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 with: context: . file: ./docker/Dockerfile @@ -80,11 +80,11 @@ jobs: # cache populated by docker-build, so this is a near-instant rebuild. needs: docker-build steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Buildx - uses: docker/setup-buildx-action@v4 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 - name: Build single-arch image for scanning (load to local daemon) - uses: docker/build-push-action@v7 + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 with: context: . file: ./docker/Dockerfile @@ -123,10 +123,10 @@ jobs: # contents-only is not enough on pull_request events. pull-requests: write steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Run gitleaks - uses: gitleaks/gitleaks-action@v3 + uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e1ee809..8e0642c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,23 +14,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up QEMU - uses: docker/setup-qemu-action@v4 + uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # v4.3.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 - name: Log in to Docker Hub - uses: docker/login-action@v4 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract metadata id: meta - uses: docker/metadata-action@v6 + uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: images: dougeubanks/gitpreserver # On a tag push {{is_default_branch}} is never true, so the old @@ -41,7 +41,7 @@ jobs: type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} - name: Build and push - uses: docker/build-push-action@v7 + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 with: context: . file: ./docker/Dockerfile @@ -86,7 +86,7 @@ jobs: } >> "$GITHUB_OUTPUT" - name: Create GitHub Release - uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 + uses: softprops/action-gh-release@e598afbe1493e6b1bafb1f389cabb956eab91231 # v3.0.3 with: # Use CHANGELOG section when found; otherwise auto-generate notes. body_path: ${{ steps.notes.outputs.found == 'true' && steps.notes.outputs.file || '' }} diff --git a/docker/Dockerfile b/docker/Dockerfile index 2dfb90a..9ee984b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -196,10 +196,7 @@ EXPOSE 6033 # stdlib http client (python3 is already a runtime dep) so we don't have to add # curl back into the slim runtime layer just for the probe. HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ - CMD python3 -c "import os,urllib.request,sys; \ -port=os.environ.get('GITPRESERVER_WEB_PORT','6033'); \ -sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:%s/healthz' % port, timeout=3).status==200 else 1)" \ - || exit 1 + CMD ["python3", "-c", "import os,urllib.request,sys; port=os.environ.get('GITPRESERVER_WEB_PORT','6033'); sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:%s/healthz' % port, timeout=3).status==200 else 1)"] WORKDIR /backups