Build and Upload #547
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |