Skip to content

Build and Upload

Build and Upload #558

Workflow file for this run

name: Build and Upload
on:
schedule:
- cron: '0 1 * * *'
push:
branches-ignore:
- 'gh-pages'
paths:
- '.github/**/*.yml'
- '.github/*.sh'
- 'scripts/**'
- 'patches/**'
- 'tests/**'
- 'files/**'
- 'build.env'
pull_request:
paths:
- '.github/**/*.yml'
- '.github/*.sh'
- 'scripts/**'
- 'patches/**'
- 'tests/**'
- 'files/**'
- 'build.env'
release:
types: [published]
workflow_dispatch:
env:
SELF_REF: ${{ github.event_name == 'schedule' && 'develop' || github.ref_name }}
jobs:
variables:
concurrency: variables-${{ github.ref_name || github.run_id }}
runs-on: ubuntu-latest
env:
ENV_FILE: ./build.env
outputs:
VERSION: ${{ steps.variables.outputs.VERSION }}
CORE_REF: ${{ steps.variables.outputs.CORE_REF }}
WEB_REF: ${{ steps.variables.outputs.WEB_REF }}
FTL_REF: ${{ steps.variables.outputs.FTL_REF }}
steps:
- name: Checkout own repository
uses: actions/checkout@v4
with:
ref: ${{ env.SELF_REF }}
- name: Set outputs
id: variables
run: |
export $(grep -v '^#' ${{ env.ENV_FILE }} | xargs -d '\n')
bash ./.github/variables.sh
cat $GITHUB_OUTPUT
build-core:
concurrency: build-core-${{ github.ref_name || github.run_id }}
needs: [variables]
runs-on: ubuntu-latest
outputs:
VERSION: ${{ steps.version.outputs.OUTPUT }}
steps:
- name: Checkout own repository
uses: actions/checkout@v4
with:
ref: ${{ env.SELF_REF }}
- name: Checkout pi-hole/pi-hole repository
uses: actions/checkout@v4
with:
repository: pi-hole/pi-hole
ref: ${{ needs.variables.outputs.CORE_REF }}
path: ./stage
- name: Cache result
id: cache
uses: ./.github/actions/cache
with:
key_prefix: core-
patches_prefix: core
- name: Apply patches
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/patch
with:
patches_prefix: core
- name: Save repository version infos
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/version
- name: Remove .git directory
run: rm -fr ./stage/.git
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: core
path: ./stage/*
include-hidden-files: true
build-web:
concurrency: build-web-${{ github.ref_name || github.run_id }}
needs: [variables]
runs-on: ubuntu-latest
outputs:
VERSION: ${{ steps.version.outputs.OUTPUT }}
steps:
- name: Checkout own repository
uses: actions/checkout@v4
with:
ref: ${{ env.SELF_REF }}
- name: Checkout pi-hole/web repository
uses: actions/checkout@v4
with:
repository: pi-hole/web
ref: ${{ needs.variables.outputs.WEB_REF }}
path: ./stage
- name: Cache result
id: cache
uses: ./.github/actions/cache
with:
key_prefix: web-
patches_prefix: web
- name: Apply patches
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/patch
with:
patches_prefix: web
- name: Save repository version infos
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/version
- name: Remove .git directory
run: rm -fr ./stage/.git
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: web
path: ./stage/*
include-hidden-files: true
build-binary:
concurrency: build-binary-${{ github.ref_name || github.run_id }}-${{ matrix.architecture }}
needs: [variables]
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.allow-failure }}
outputs:
VERSION: ${{ steps.version.outputs.OUTPUT }}
strategy:
fail-fast: false
matrix:
include:
- architecture: amd64
docker_platform: linux/amd64
allow-failure: false
# - architecture: 386
# docker_platform: linux/386 # EOS by Entware team
# allow-failure: true
# - architecture: armv5
# docker_platform: linux/arm/v5 # EOS by Entware team / Not supported by Pi-hole
# allow-failure: true
# - architecture: armv6
# docker_platform: linux/arm/v6 # Not supported by Entware
# allow-failure: true
- architecture: armv7
docker_platform: linux/arm/v7
allow-failure: false
- architecture: arm64
docker_platform: linux/arm64/v8
allow-failure: false
# - architecture: mipsel
# docker_platform: linux/mipsel # Not supported by Pi-hole
# allow-failure: true
# - architecture: mips
# docker_platform: linux/mips # Not supported by Pi-hole
# allow-failure: true
steps:
- name: Checkout own repository
uses: actions/checkout@v4
with:
ref: ${{ env.SELF_REF }}
- name: Checkout pi-hole/FTL repository
uses: actions/checkout@v4
with:
repository: pi-hole/FTL
ref: ${{ needs.variables.outputs.FTL_REF }}
path: ./stage
- name: Cache result
id: cache
uses: ./.github/actions/cache
with:
key_prefix: binary-${{ matrix.architecture }}-
patches_prefix: ftl
files: |
./stage/pihole-FTL-*
./stage/.version
- name: Apply patches
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/patch
with:
patches_prefix: ftl
- name: Save repository version infos
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/version
- name: Set required variables
if: steps.cache.outputs.cache-hit != 'true'
id: variables
working-directory: ./stage
run: |
GIT_TAG=$(git describe --tags --abbrev=0 2> /dev/null || echo "")
echo "GIT_BRANCH=$([ -n "${GIT_TAG}" ] && echo "master" || git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT
echo "GIT_TAG=$GIT_TAG" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
if: steps.cache.outputs.cache-hit != 'true'
uses: docker/setup-buildx-action@v3
#- name: Do not run tests
# if: steps.cache.outputs.cache-hit != 'true'
# continue-on-error: true
# run: sed '/build.sh/ s/ test / /' -i ./stage/.github/Dockerfile
- name: Build and test FTL
if: steps.cache.outputs.cache-hit != 'true'
uses: Wandalen/wretry.action/main@v3
with:
action: docker/build-push-action@v5
attempt_limit: 3
retry_condition: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'schedule' }}
with: |
platforms: ${{ matrix.docker_platform }}
pull: true
push: false
context: ./stage
target: result
file: ./stage/.github/Dockerfile
outputs: |
type=tar,dest=./stage/build.tar
build-args: |
"CI_ARCH=${{ matrix.docker_platform }}"
"GIT_BRANCH=${{ steps.variables.outputs.GIT_BRANCH }}"
"GIT_TAG=${{ steps.variables.outputs.GIT_TAG }}"
- name: Extract FTL binary and generate checksum file
if: steps.cache.outputs.cache-hit != 'true'
working-directory: ./stage
run: |
tar -xf ./build.tar pihole-FTL
mv pihole-FTL "pihole-FTL-${{ matrix.architecture }}"
sha1sum pihole-FTL-* > "pihole-FTL-${{ matrix.architecture }}.sha1"
- name: Remove .git directory
run: rm -fr ./stage/.git
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.architecture }}
path: |
./stage/pihole-FTL-*
./stage/.version
include-hidden-files: true
build-packages:
concurrency: build-packages-${{ github.ref_name || github.run_id }}
needs: [variables, build-core, build-web, build-binary]
runs-on: ubuntu-latest
outputs:
IPK_VERSION: ${{ steps.versions.outputs.IPK }}
CORE_VERSION: ${{ steps.versions.outputs.CORE }}
WEB_VERSION: ${{ steps.versions.outputs.WEB }}
FTL_VERSION: ${{ steps.versions.outputs.FTL }}
steps:
- name: Checkout own repository
uses: actions/checkout@v4
with:
ref: ${{ env.SELF_REF }}
- name: Download core artifact
uses: actions/download-artifact@v4
with:
name: core
path: ./artifacts/core
- name: Download web artifact
uses: actions/download-artifact@v4
with:
name: web
path: ./artifacts/web
- name: Download binary artifacts
uses: actions/download-artifact@v4
with:
pattern: binary-*
path: ./artifacts/binary
- name: Add '-dev' to package name
if: ${{ github.ref_name == 'develop' || github.event_name == 'schedule' }}
run: sed '/^Package:/ s/$/-dev/' -i ./files/CONTROL/control
- name: Build packages
run: |
mkdir -p ./build ./packages
sudo -E bash ./scripts/multibuild.sh ./build "${{ needs.variables.outputs.VERSION }}" ./artifacts ./packages
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: packages
path: ./packages/*
include-hidden-files: true
- name: Save current module versions
run: |
. ./artifacts/core/.version
echo "CORE=$VERSION" >> ./.versions
. ./artifacts/web/.version
echo "WEB=$VERSION" >> ./.versions
. ./artifacts/binary/.version
echo "FTL=$VERSION" >> ./.versions
- name: Check if same dev package was already build
id: devcheck
if: ${{ github.event_name == 'schedule' }}
uses: ./.github/actions/devcheck
- name: Set versions
if: ${{ github.event_name != 'schedule' || steps.devcheck.outputs.cache-hit != 'true' }}
id: versions
run: |
if [ -f ./.versions ]; then
echo "IPK=${{ needs.variables.outputs.VERSION }}" >> $GITHUB_OUTPUT
cat ./.versions >> $GITHUB_OUTPUT
fi
release:
concurrency: release-${{ github.ref_name || github.run_id }}
needs: [build-packages]
if: ${{ startsWith(github.ref, 'refs/tags/') && needs.build-packages.outputs.IPK_VERSION != '' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: packages
path: ./artifacts
- name: Create changelog file
env:
CORE_VERSION: ${{ needs.build-packages.outputs.CORE_VERSION }}
WEB_VERSION: ${{ needs.build-packages.outputs.WEB_VERSION }}
FTL_VERSION: ${{ needs.build-packages.outputs.FTL_VERSION }}
run: |
CORE_VERSION_OUT="[$CORE_VERSION](https://github.com/pi-hole/pi-hole/releases/tag/$CORE_VERSION)"
WEB_VERSION_OUT="[$WEB_VERSION](https://github.com/pi-hole/web/releases/tag/$WEB_VERSION)"
FTL_VERSION_OUT="[$FTL_VERSION](https://github.com/pi-hole/FTL/releases/tag/$FTL_VERSION)"
[ "$(echo "$CORE_VERSION" | cut -c1)" != "v" ] && CORE_VERSION_OUT="[$CORE_VERSION](https://github.com/pi-hole/pi-hole/commit/$CORE_VERSION)"
[ "$(echo "$WEB_VERSION" | cut -c1)" != "v" ] && WEB_VERSION_OUT="[$WEB_VERSION](https://github.com/pi-hole/web/commit/$WEB_VERSION)"
[ "$(echo "$FTL_VERSION" | cut -c1)" != "v" ] && FTL_VERSION_OUT="[$FTL_VERSION](https://github.com/pi-hole/FTL/commit/$FTL_VERSION)"
echo "Core version: $CORE_VERSION_OUT " >> changelog.md
echo "Web version: $WEB_VERSION_OUT " >> changelog.md
echo "FTL version: $FTL_VERSION_OUT " >> changelog.md
- name: Create or Edit a release
uses: softprops/action-gh-release@v2
with:
files: ./artifacts/*/*.ipk
tag_name: ${{ needs.build-packages.outputs.IPK_VERSION }}
body_path: changelog.md
append_body: true
generate_release_notes: true
upload:
concurrency: upload
needs: [build-packages]
if: ${{ needs.build-packages.outputs.IPK_VERSION != '' && (startsWith(github.ref, 'refs/tags/') || github.ref_name == 'develop' || github.event_name == 'schedule' || github.ref_name == 'master') }}
# @TODO when v6 is released master should not trigger this job
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout own repository
uses: actions/checkout@v4
with:
ref: ${{ env.SELF_REF }}
fetch-depth: 0
sparse-checkout: /.github/*
sparse-checkout-cone-mode: false
- name: Checkout gh-pages branch
uses: actions/checkout@v4
continue-on-error: true
with:
ref: gh-pages
path: ./gh-pages
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: packages
path: ./artifacts
- name: Collect new packages
run: |
mkdir -p ./gh-pages
find ./artifacts -mindepth 1 -maxdepth 1 -type d -name "*-*.*" -exec bash -c '
[ -z "$(ls -A "$1")" ] && exit
ARCHITECTURE=$(basename "$1")
echo "Removing old packages for $ARCHITECTURE"
if [ "$(find "$1" -maxdepth 1 -type f -name "*-dev_*.ipk" -print -quit)" ]; then
find "./gh-pages/$ARCHITECTURE" -maxdepth 2 -type f -name "*-dev_*.ipk" -delete -print
else
find "./gh-pages/$ARCHITECTURE" -maxdepth 2 -type f \( -name "*.ipk" ! -name "*-dev_*.ipk" \) -delete -print
fi
' bash {} \;
cp -rv ./artifacts/* ./gh-pages
- name: Checkout Entware/ipk-html-indexer repository
uses: actions/checkout@v4
with:
repository: Entware/ipk-html-indexer
path: ./ipk-html-indexer
- name: Run ipk-html-indexer
run: |
sudo ln -s "$(readlink -f ./ipk-html-indexer/mkindex.py)" /usr/local/bin/mkindex.py
sudo ln -s "$(readlink -f ./ipk-html-indexer/mkhtml.py)" /usr/local/bin/mkhtml.py
find ./gh-pages -depth \( -type f -name "Packages*" -o -type d -name "css" \) -exec rm -fr "{}" \;
find ./gh-pages -mindepth 1 -maxdepth 1 -type d -name "*-*.*" -exec bash -c '
bash ./ipk-html-indexer/index_feed.sh -h -f "$1"
sed "s#href=\"/css#href=\"../css#" -i "$1/Packages.html"
' bash {} \;
cp -fr ./ipk-html-indexer/css ./gh-pages
- name: Cleanup gh-pages directory
run: |
find ./gh-pages -mindepth 1 -maxdepth 1 -type d -regextype sed \( ! -regex '.*/[[:alnum:]]*-k[0-9]*\.[0-9]*$' ! -name ".git" ! -name "css" \) -exec rm -frv "{}" \;
find ./gh-pages -mindepth 1 -maxdepth 1 -type f ! -name "Packages*" -exec rm -fv "{}" \;
- name: Create directory listings
uses: ./.github/actions/index
with:
path: ./gh-pages
ignored: css
- name: List files
uses: ./.github/actions/list
with:
paths: . ./artifacts ./gh-pages
- name: Prepare for upload
run: |
find . -mindepth 1 -maxdepth 1 \( ! -name "gh-pages" -type d -exec rm -fr "{}" \; \) -o \( -type f -exec rm -f "{}" \; \)
shopt -s dotglob && mv -v ./gh-pages/* .
- name: Rename gh-pages branch
continue-on-error: true
run: git branch -m gh-pages gh-pages.old
- name: Upload packages
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: .
commit-message: Upload
single-commit: true
force: true
git-config-name: 'github-actions[bot]'
git-config-email: '41898282+github-actions[bot]@users.noreply.github.com'