From d9c5fa7b688dd1700f673f42aa2e04f2dfae7a94 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Thu, 26 Jan 2023 14:01:33 +0100 Subject: [PATCH] New workflow to trigger automatic image builds This is executed daily and performs various checks: - Is there a newer timezonedb extension available. - (more coming soon). And, if there is any of the checks happening, it automatically dispatches a reposity_dispatch (auto-build-triggered) event, causing the test and build workflow to be triggered. Now the test & build workflow supports workflow_call events That way we can make other workflows in the repository to, conditionally, launch a rebuild when some conditions are met: - When there is a new version of an extension. - When there is a new PHP release. - After X days - ... Note this is related to https://tracker.moodle.org/browse/MDL-76675 Also, update some actions to use new nodejs versions and avoid some deprecation warnings. --- .github/workflows/test_buildx_and_publish.yml | 24 +++--- .github/workflows/trigger_new_builds.yml | 86 +++++++++++++++++++ 2 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/trigger_new_builds.yml diff --git a/.github/workflows/test_buildx_and_publish.yml b/.github/workflows/test_buildx_and_publish.yml index 34019fa..64ab1b9 100644 --- a/.github/workflows/test_buildx_and_publish.yml +++ b/.github/workflows/test_buildx_and_publish.yml @@ -1,6 +1,10 @@ name: Test and publish -on: [push, pull_request, workflow_dispatch] +on: + push: + pull_request: + workflow_dispatch: + workflow_call: env: REPOSITORY: moodle-php-apache @@ -12,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Build image run: | @@ -35,18 +39,18 @@ jobs: Publish: # Completely avoid forks and pull requests to try this job. - if: github.repository_owner == 'moodlehq' && contains(fromJson('["push", "workflow_dispatch"]'), github.event_name) + if: github.repository_owner == 'moodlehq' && contains(fromJson('["push", "workflow_dispatch", "workflow_call"]'), github.event_name) # Requires Test to pass needs: Test runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Calculate the tags to be pussed to the registries. - name: Calculate image tag names id: calculatetags - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: | ${{ env.DOCKERHUB_OWNER }}/${{ env.REPOSITORY }} @@ -58,22 +62,22 @@ jobs: # https://github.com/docker/setup-qemu-action#usage - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 # https://github.com/marketplace/actions/docker-setup-buildx - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 # https://github.com/docker/login-action#docker-hub - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} # https://github.com/docker/login-action#github-container-registry - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ secrets.GH_USERNAME }} @@ -81,7 +85,7 @@ jobs: # https://github.com/docker/build-push-action#multi-platform-image - name: Build and push to Docker Hub and Github registries - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . file: Dockerfile diff --git a/.github/workflows/trigger_new_builds.yml b/.github/workflows/trigger_new_builds.yml new file mode 100644 index 0000000..3c82527 --- /dev/null +++ b/.github/workflows/trigger_new_builds.yml @@ -0,0 +1,86 @@ +name: Trigger new builds based on various criteria. + +# If any of the criteria happens, they set the trigger_build +# output variable to 'true' and the rebuild will happen. + +on: + workflow_dispatch: + schedule: + # Fridays 16:00 UTC + - cron: '10 16 * * 5' + +jobs: + + # This job compares the currently used timezonedb extension version + # in the docker images with the latest timezonedb release (tag) available + # @ https://github.com/php/pecl-datetime-timezonedb repository. + # If different, a rebuilt will be triggered. + datetimedb-new-release: + # Completely avoid forks and pull requests to try this job. + if: github.repository_owner == 'moodlehq' && contains(fromJson('["workflow_dispatch", "schedule"]'), github.event_name) + runs-on: ubuntu-latest + + outputs: + trigger_build: ${{ steps.calculate.outputs.result }} + + steps: + + - name: Configuring git vars + uses: rlespinasse/github-slug-action@v4 + + - name: Compare current and latest datetimedb versions + id: calculate + run: | + # Calculate current image version + # If the branch has has X.Y-xxxxx format, use it as docker tag. Else, use "dev" image (master branch). + tag=dev + if [[ ${{ env.GITHUB_REF_SLUG }} =~ \d+\.\d+\-\w+ ]]; then + tag=${{ env.GITHUB_REF_SLUG }} + fi + echo "LOG: docker tag: $tag" + + # Extract the timezonedb version from the image. + current=$(docker run -t --rm moodlehq/moodle-php-apache:$tag php -r 'echo timezone_version_get();') + echo "LOG: current: $current" + + # Look for the latest tag available @ https://github.com/php/pecl-datetime-timezonedb + latest=$(curl -s "https://api.github.com/repos/php/pecl-datetime-timezonedb/tags" | jq -r '.[0].name') + echo "LOG: latest: $latest" + + # Compare the versions (digits only), if current < latest, then we need to rebuild. + if [[ ${current//[!0-9]/} -lt ${latest//[!0-9]/} ]]; then + echo "result=true" >> $GITHUB_OUTPUT + echo "LOG: timezonedb to trigger image build" + fi + + # This job gets the results of all the jobs in the workflow and, + # if any of them has ended with the "trigger_build" output set, then + # will set its own (final) trigger_build output to 'true'. + evaluate: + # Completely avoid forks and pull requests to try this job. + if: github.repository_owner == 'moodlehq' && contains(fromJson('["workflow_dispatch", "schedule"]'), github.event_name) + runs-on: ubuntu-latest + needs: [datetimedb-new-release] + + outputs: + trigger_build: ${{ steps.evaluate.outputs.trigger }} + + steps: + + - name: Evaluate if we have to trigger a build + id: evaluate + run: | + # Add here more conditions (ORed) when new criteria are added. + if [[ ${{ needs.datetimedb-new-release.outputs.trigger_build }} ]]; then + echo "trigger=true" >> $GITHUB_OUTPUT + echo "LOG: Final evaluation, trigger the build" + fi + + Build: + # Only if the final workflow.outputs.trigger_build from evaluate job has decided to build. + if: ${{ needs.evaluate.outputs.trigger_build }} == 'true' + needs: [evaluate] + + # Launch the build job (as reusable workflow). + uses: ./.github/workflows/test_buildx_and_publish.yml + secrets: inherit