diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8a3c423..a350cbf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,51 @@ updates: target-branch: dev reviewers: - "pi-hole/docker-maintainers" + - package-ecosystem: "docker" + directory: "/src/" + schedule: + interval: "weekly" + day: saturday + time: "10:00" + target-branch: dev + reviewers: + - "pi-hole/docker-maintainers" + - package-ecosystem: pip + directory: "/test" + schedule: + interval: weekly + day: saturday + time: "10:00" + open-pull-requests-limit: 10 + target-branch: dev + reviewers: + - "pi-hole/docker-maintainers" + # Maintain dependencies for GitHub Actions development-v6 + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: saturday + time: "10:00" + target-branch: development-v6 + reviewers: + - "pi-hole/docker-maintainers" + - package-ecosystem: "docker" + directory: "/src/" + schedule: + interval: "weekly" + day: saturday + time: "10:00" + target-branch: development-v6 + reviewers: + - "pi-hole/docker-maintainers" + - package-ecosystem: pip + directory: "/test" + schedule: + interval: weekly + day: saturday + time: "10:00" + open-pull-requests-limit: 10 + target-branch: development-v6 + reviewers: + - "pi-hole/docker-maintainers" diff --git a/.github/workflows/housekeeping.yml b/.github/workflows/housekeeping.yml new file mode 100644 index 0000000..afb3651 --- /dev/null +++ b/.github/workflows/housekeeping.yml @@ -0,0 +1,28 @@ +name: housekeeping +on: + workflow_dispatch: + +jobs: + housekeeping: + runs-on: ubuntu-latest + steps: + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to GitHub Container Registry with PAT_TOKEN + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.PAT_TOKEN }} + - + name: Delete all containers from repository without tags + uses: Chizkiyahu/delete-untagged-ghcr-action@v4 + with: + token: ${{ secrets.PAT_TOKEN }} + repository_owner: ${{ github.repository_owner }} + repository: ${{ github.repository }} + untagged_only: true + owner_type: org # or user + except_untagged_multiplatform: true \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 337aff9..e768463 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,12 +2,16 @@ name: Mark stale issues on: schedule: - - cron: '0 8 * * *' + - cron: '0 8 * * *' workflow_dispatch: + issue_comment: + +env: + stale_label: stale jobs: - stale: - + stale_action: + if: github.event_name != 'issue_comment' runs-on: ubuntu-latest permissions: issues: write @@ -19,8 +23,27 @@ jobs: days-before-stale: 30 days-before-close: 5 stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Please comment or update this issue or it will be closed in 5 days.' - stale-issue-label: 'stale' - exempt-issue-labels: 'pinned, Fixed in next release, bug, never-stale, documentation, investigating' + stale-issue-label: '${{ env.stale_label }}' + exempt-issue-labels: 'pinned, Fixed in next release, bug, never-stale, documentation, investigating, v6' exempt-all-issue-assignees: true operations-per-run: 300 close-issue-reason: 'not_planned' + + remove_stale: + # trigger "stale" removal immediately when stale issues are commented on + # we need to explicitly check that the trigger does not run on comment on a PR as + # 'issue_comment' triggers on issues AND PR comments + # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment-on-issues-only-or-pull-requests-only + if: ${{ !github.event.issue.pull_request && github.event_name != 'schedule' }} + permissions: + contents: read # for actions/checkout + issues: write # to edit issues label + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Remove 'stale' label + run: gh issue edit ${{ github.event.issue.number }} --remove-label ${{ env.stale_label }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/test-and-build-v6.yml b/.github/workflows/test-and-build-v6.yml new file mode 100644 index 0000000..09d2dde --- /dev/null +++ b/.github/workflows/test-and-build-v6.yml @@ -0,0 +1,147 @@ +name: Build and Publish (development-v6) +on: + schedule: + - cron: "0 5 * * *" + push: + branches: + - development-v6 + +env: + dockerhub: ${{ secrets.DOCKERHUB_NAMESPACE }}/pihole + ghcr: ghcr.io/${{ github.repository_owner }}/pihole + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + platform: [linux/amd64, linux/386, linux/arm/v6, linux/arm/v7, linux/arm64] + alpine_version: [3.19] + include: + - platform: linux/riscv64 + alpine_version: edge + + steps: + - name: Prepare name for digest up/download + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Checkout Repo + uses: actions/checkout@v4 + with: + ref: development-v6 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + images: | + ${{ env.dockerhub }} + ${{ env.ghcr }} + flavor: | + latest=false + tags: | + development-v6 + + - name: Login to DockerHub and GitHub Container Registry + uses: ./.github/actions/login-repo + with: + docker_username: ${{ secrets.DOCKERHUB_USER }} + docker_password: ${{ secrets.DOCKERHUB_PASS }} + ghcr_username: ${{ github.repository_owner }} + ghcr_password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: ${{ matrix.platform}} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build container and push by digest + id: build + uses: docker/build-push-action@v6 + with: + context: ./src/ + platforms: ${{ matrix.platform }} + build-args: | + PIHOLE_DOCKER_TAG=${{ steps.meta.outputs.version }} + alpine_version=${{ matrix.alpine_version }} + labels: ${{ steps.meta.outputs.labels }} + outputs: | + type=image,name=${{ env.dockerhub }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digests + run: | + mkdir -p /tmp/digests + digest_docker="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest_docker#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + # Merge all the digests into a single file + # If we would push immediately above, the individual runners would overwrite each other's images + # https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners + merge-and-deploy: + runs-on: ubuntu-latest + needs: + - build + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + ref: development-v6 + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + images: | + ${{ env.dockerhub }} + ${{ env.ghcr }} + flavor: | + latest=false + tags: | + development-v6 + + - name: Login to DockerHub and GitHub Container Registry + uses: ./.github/actions/login-repo + with: + docker_username: ${{ secrets.DOCKERHUB_USER }} + docker_password: ${{ secrets.DOCKERHUB_PASS }} + ghcr_username: ${{ github.repository_owner }} + ghcr_password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push (DockerHub and GitHub Container Registry) + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.dockerhub }}@sha256:%s ' *) + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.ghcr }}@sha256:%s ' *) + + - name: Inspect images + run: | + docker buildx imagetools inspect ${{ env.dockerhub }}:${{ steps.meta.outputs.version }} + docker buildx imagetools inspect ${{ env.ghcr }}:${{ steps.meta.outputs.version }} \ No newline at end of file diff --git a/README.md b/README.md index b1b6aa8..2bf4d5e 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ Do not attempt to upgrade (`pihole -up`) or reconfigure (`pihole -r`). New imag - If you care about your data (logs/customizations), make sure you have it volume-mapped or it will be deleted in this step. 3. Start your container with the newer base image: `docker run pihole/pihole` (`` being your preferred run volumes and env vars) -Why is this style of upgrading good? A couple reasons: Everyone is starting from the same base image which has been tested to known it works. No worrying about upgrading from A to B, B to C, or A to C is required when rolling out updates, it reduces complexity, and simply allows a 'fresh start' every time while preserving customizations with volumes. Basically I'm encouraging [phoenix server](https://www.google.com/?q=phoenix+servers) principles for your containers. +Why is this style of upgrading good? A couple reasons: Everyone is starting from the same base image which has been tested to known it works. No worrying about upgrading from A to B, B to C, or A to C is required when rolling out updates, it reduces complexity, and simply allows a 'fresh start' every time while preserving customizations with volumes. Basically I'm encouraging [phoenix server](https://martinfowler.com/bliki/PhoenixServer.html) principles for your containers. To reconfigure Pi-hole you'll either need to use an existing container environment variables or if there is no a variable for what you need, use the web UI or CLI commands. diff --git a/test/cmd.sh b/test/cmd.sh index ef40a29..d5d9773 100755 --- a/test/cmd.sh +++ b/test/cmd.sh @@ -5,7 +5,7 @@ docker buildx build ./src --build-arg TARGETPLATFORM="${TARGETPLATFORM}" --tag p docker images pihole:${GIT_TAG} # auto-format the pytest code -python -m black ./test/tests/ +python3 -m black ./test/tests/ # TODO: Add junitxml output and have something consume it COLUMNS=120 py.test -vv -n auto ./test/tests/