From 025ccb8e8c2740a5faf1b51d08284c90a94efcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chastanet?= Date: Sat, 18 May 2024 00:55:01 +0200 Subject: [PATCH] frankenphp binary file megalinter workflow only if not cancelled --- .cspell/config.txt | 1 + .../build-frankenphp-docker-image.yml | 490 ++++++++++++++++++ .github/workflows/lint-test.yml | 13 +- command-configurator/Dockerfile | 61 ++- 4 files changed, 552 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/build-frankenphp-docker-image.yml diff --git a/.cspell/config.txt b/.cspell/config.txt index cec760cd..f4636b08 100644 --- a/.cspell/config.txt +++ b/.cspell/config.txt @@ -142,6 +142,7 @@ PRUNEPATHS publickey rearranger refact +reqs Resolv riak RPAREN diff --git a/.github/workflows/build-frankenphp-docker-image.yml b/.github/workflows/build-frankenphp-docker-image.yml new file mode 100644 index 00000000..93a30abe --- /dev/null +++ b/.github/workflows/build-frankenphp-docker-image.yml @@ -0,0 +1,490 @@ +--- +# Generate frankenphp binary file +name: build-frankenphp-docker-image +on: # yamllint disable-line rule:truthy + workflow_dispatch: + +jobs: + # ------------------------------------------------------- + # Build frankenphp docker image + # ------------------------------------------------------- + build-frankenphp-docker-image: + runs-on: ubuntu-22.04 + permissions: + # needed by akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + statuses: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # overall process + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: build-frankenphp-binary-file + status: pending + + - name: Set env vars + id: vars + # shellcheck disable=SC2129 + run: | + ( + echo "updateDate=$(date '+%Y-%m')" + echo "job_tag=${{github.run_id}}" + echo "image_tag=latest" + echo "image_name=scrasnups/frankenphp-composer-onbuild" + echo "branch_name=${GITHUB_REF##*/}" + ) >> "${GITHUB_ENV}" + + - uses: docker/build-push-action@v5 + continue-on-error: false + with: + load: true + context: command-configurator + file: command-configurator/Dockerfile + target: build-bin-file + pull: true + github-token: ${{ github.token }} + build-args: | + UPDATE_DATE: "${{ env.updateDate }}" + cache-from: | + type=registry,ref=${{ env.image_name }}:cache-base-${{ env.image_tag }} + tags: static-app + + - name: Check and copy binary + continue-on-error: false + run: | + set -exo pipefail + storeContainer="$(docker create --name static-app-tmp static-app)" + docker cp "${storeContainer}:/go/src/app/dist/frankenphp-linux-x86_64" my-app + docker rm static-app-tmp + mv my-app command-configurator + + - name: Upload binary artifact + if: success() + uses: actions/upload-artifact@v4 + with: + name: command-configurator + path: command-configurator + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: build-frankenphp-binary-file + status: ${{ job.status }} + + # ------------------------------------------------------- + # Build bash docker images + # ------------------------------------------------------- + build-bash-docker-images: + runs-on: ubuntu-22.04 + permissions: + # needed by akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + statuses: write + strategy: + fail-fast: true + matrix: + vendor: + - ubuntu + - alpine + bashTarVersion: + - "4.4" + - "5.0" + - "5.3" + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # overall process + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: build-bash-tools + status: pending + + - name: Set env vars + id: vars + # shellcheck disable=SC2129 + run: | + ( + echo "job_tag=${{github.run_id}}-${{matrix.vendor}}-${{matrix.bashTarVersion}}" + echo "image_tag=bash-tools-${{matrix.vendor}}-${{matrix.bashTarVersion}}" + echo "image_name=scrasnups/build" + echo "branch_name=${GITHUB_REF##*/}" + if [[ "${{ matrix.vendor }}" = "ubuntu" ]]; then + echo "bashImage=ubuntu:20.04" + else + echo "bashImage=amd64/bash:${{ matrix.bashTarVersion }}-alpine3.19" + fi + ) >> "${GITHUB_ENV}" + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: build-${{ env.image_tag }} + status: pending + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as base name for tags + images: | + ${{env.image_name}} + # generate Docker tags based on the following events/attributes + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + - uses: docker/build-push-action@v5 + continue-on-error: false + with: + load: true + context: .docker + file: .docker/Dockerfile.${{ matrix.vendor }} + pull: true + github-token: ${{ github.token }} + tags: | + ${{ env.image_name }}:${{ env.image_tag }} + build-args: | + BASH_IMAGE: "${{ env.bashImage }}" + BASH_TAR_VERSION: "${{ matrix.bashTarVersion }}" + cache-from: type=gha,scope=${{ env.image_tag }} + cache-to: type=gha,mode=max,scope=${{ env.image_tag }} + - name: Check image + continue-on-error: false + run: | + docker run --rm "${{ env.image_name }}:${{ env.image_tag }}" bash --version + - uses: docker/build-push-action@v5 + continue-on-error: false + with: + load: true + context: .docker + file: .docker/Dockerfile.${{ matrix.vendor }} + push: true + github-token: ${{ github.token }} + tags: | + ${{ env.image_name }}:${{ env.image_tag }} + ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-to: type=gha,mode=max,scope=${{ env.image_tag }} + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: build-${{ env.image_tag }} + status: ${{ job.status }} + + # ------------------------------------------------------- + # Pre-commit + # ------------------------------------------------------- + + pre-commit: + runs-on: ubuntu-22.04 + needs: [build-bash-docker-images] + permissions: + # needed by akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + statuses: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - uses: crazy-max/ghaction-import-gpg@v6 + if: ${{ success() }} + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - uses: tibdex/github-app-token@v1 + if: ${{ success() }} + id: generate-token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: pre-commit-megalinter + status: pending + + - name: Set env vars + id: vars + # shellcheck disable=SC2129 + run: | + ( + echo "branch_name=${GITHUB_REF##*/}" + ) >> "${GITHUB_ENV}" + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.9 + + - uses: fchastanet/github-action-setup-shfmt@v4.0.0 + + - name: Install requirements + run: | + set -exo pipefail + + bin/installRequirements + + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 + id: preCommit + with: + extra_args: >- + -c .pre-commit-config-github.yaml -a --hook-stage manual + + - name: MegaLinter + id: ml + if: ${{ !cancelled() }} + # You can override MegaLinter flavor used to have faster performances + # More info at https://megalinter.io/flavors/ + uses: oxsecurity/megalinter/flavors/terraform@v7 + # All available variables are described in documentation + # https://megalinter.io/configuration/ + env: + # Validates all source when push on master, + # else just the git diff with master. + # Override with true if you always want to lint all sources + VALIDATE_ALL_CODEBASE: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MEGALINTER_CONFIG: .mega-linter-githubAction.yml + CI_MODE: 1 + + - name: Upload MegaLinter artifacts + if: success() || failure() + uses: actions/upload-artifact@v4 + with: + name: MegaLinter reports + path: | + megalinter-reports + mega-linter.log + + - name: MegaLinter/Precommit has updated sources + if: > + steps.preCommit.outcome == 'failure' || ( + steps.ml.outputs.has_updated_sources == 1 && ( + env.APPLY_FIXES_EVENT == 'all' || + env.APPLY_FIXES_EVENT == github.event_name + ) + ) + run: | + echo "COND_UPDATED_SOURCES=true" >> "${GITHUB_ENV}" + + - name: is apply fixes needed ? + if: > + env.APPLY_FIXES_MODE == 'pull_request' && ( + github.event_name == 'push' || + github.event.pull_request.head.repo.full_name == + github.repository + ) + run: | + echo "COND_APPLY_FIXES_NEEDED=true" >> "${GITHUB_ENV}" + + - name: Create Pull Request + id: cpr + # prettier-ignore + if: > + env.COND_UPDATED_SOURCES == 'true' && + env.COND_APPLY_FIXES_NEEDED == 'true' && + !contains(github.event.head_commit.message, 'skip fix') + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ steps.generate-token.outputs.token }} + committer: fchastanet + branch: update/pre-commit-fixes-${{ env.branch_name }} + delete-branch: true + title: lint fixes + commit-message: Auto-update lint fixes + body: | + some auto fixes have been generated during pre-commit run + labels: pre-commit-fixes + + - name: Print Pull request created + if: | + steps.cpr.outputs.pull-request-number && + steps.cpr.outcome == 'success' + run: | + echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + if: ${{ always() }} + with: + name: pre-commit-megalinter + status: ${{ job.status }} + + # ------------------------------------------------------- + # Unit tests + # ------------------------------------------------------- + + unit-tests: + runs-on: ubuntu-22.04 + needs: [build-bash-docker-images] + permissions: + # needed by akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + statuses: write + # needed by mikepenz/action-junit-report@v4 + checks: write + strategy: + fail-fast: true + matrix: + vendor: + - ubuntu + - alpine + bashTarVersion: + - "4.4" + - "5.0" + - "5.3" + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - uses: crazy-max/ghaction-import-gpg@v6 + if: ${{ success() }} + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - uses: tibdex/github-app-token@v1 + if: ${{ success() }} + id: generate-token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: unit-tests-${{matrix.vendor}}-${{matrix.bashTarVersion}} + status: pending + + - name: Set env vars + id: vars + # shellcheck disable=SC2129 + run: | + ( + echo "job_tag=${{github.run_id}}-${{matrix.vendor}}-${{matrix.bashTarVersion}}" + echo "image_tag=bash-tools-${{matrix.vendor}}-${{matrix.bashTarVersion}}" + echo "image_name=scrasnups/build" + echo "branch_name=${GITHUB_REF##*/}" + if [[ "${{ matrix.vendor }}" = "ubuntu" ]]; then + echo "bashImage=ubuntu:20.04" + echo "batsOptions=-j 30" + else + echo "bashImage=amd64/bash:${{ matrix.bashTarVersion }}-alpine3.19" + echo "batsOptions=-j 30 --filter-tags '!ubuntu_only'" + fi + ) >> "${GITHUB_ENV}" + + - name: run unit tests + id: unitTests + run: | + set -exo pipefail + + bin/installRequirements + + chmod 777 logs + + docker pull "scrasnups/build:${{env.image_tag}}" + + status=0 + docker run --rm \ + -e KEEP_TEMP_FILES=0 \ + -e BATS_FIX_TEST=0 \ + -e USER_ID="1000" \ + -e GROUP_ID="1000" \ + --user "www-data:www-data" \ + -w /bash \ + -v "$(pwd):/bash" \ + "scrasnups/build:${{env.image_tag}}" \ + /bash/vendor/bats/bin/bats \ + ${{env.batsOptions}} \ + --formatter junit -o logs -r src 2>&1 | + tee "logs/bats-${{ env.job_tag }}.log" || status=$? + + awk '/xml version="1.0"/{flag=1} flag; /<\/testsuites>/{flag=0}' \ + "logs/bats-${{ env.job_tag }}.log" >"logs/junit-${{ env.job_tag }}.xml" + exit "${status}" + + - name: Publish Test Report + uses: mikepenz/action-junit-report@v4 + if: ${{ always() }} + with: + token: ${{ github.token }} + check_name: JUnit ${{ env.image_tag }} + fail_on_failure: true + require_tests: true + require_passed_tests: true + report_paths: "logs/**.xml" + + - name: Upload Test Results + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: Test Results ${{ env.image_tag }} + path: | + logs/** + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: unit-tests-${{matrix.vendor}}-${{matrix.bashTarVersion}} + status: ${{ job.status }} + + overallTestResults: + name: "Overall Tests Results" + if: ${{ always() }} + needs: [unit-tests] + runs-on: ubuntu-22.04 + permissions: + # needed by akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + statuses: write + + steps: + # run this action to get the workflow conclusion + # You can get the conclusion via env (env.WORKFLOW_CONCLUSION) + - uses: AbsoLouie/workflow-conclusion-status@v1.0.2 + + - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 + with: + name: build-bash-tools + # neutral, success, skipped, cancelled, timed_out, action_required, failure + status: ${{ env.WORKFLOW_CONCLUSION }} diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml index bb1eef45..78b97976 100644 --- a/.github/workflows/lint-test.yml +++ b/.github/workflows/lint-test.yml @@ -88,6 +88,7 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha + - uses: docker/build-push-action@v5 continue-on-error: false with: @@ -98,26 +99,34 @@ jobs: github-token: ${{ github.token }} build-args: | UPDATE_DATE: "${{ env.updateDate }}" + target: base tags: | ${{ env.image_name }}:${{ env.image_tag }} cache-from: | - type=registry,ref=${{ env.image_name }}:${{ env.image_tag }} + type=registry,ref=${{ env.image_name }}:cache-base-${{ env.image_tag }} + cache-to: | + type=registry,ref=${{ env.image_name }}:cache-base-${{ env.image_tag }},mode=max + - name: Check image continue-on-error: false run: | docker run --rm "${{ env.image_name }}:${{ env.image_tag }}" php --version + - uses: docker/build-push-action@v5 continue-on-error: false with: load: true context: command-configurator file: command-configurator/Dockerfile + target: base push: true github-token: ${{ github.token }} tags: | ${{ env.image_name }}:${{ env.image_tag }} ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + cache-from: | + type=registry,ref=${{ env.image_name }}:cache-base-${{ env.image_tag }} - uses: akatov/commit-status-updater@a9e988ec5454692ff7745a509452422a35172ad6 with: @@ -308,7 +317,7 @@ jobs: - name: MegaLinter id: ml - if: ${{ always() }} + if: ${{ !cancelled() }} # You can override MegaLinter flavor used to have faster performances # More info at https://megalinter.io/flavors/ uses: oxsecurity/megalinter/flavors/terraform@v7 diff --git a/command-configurator/Dockerfile b/command-configurator/Dockerfile index 9271be2f..e1ece2ac 100644 --- a/command-configurator/Dockerfile +++ b/command-configurator/Dockerfile @@ -1,18 +1,19 @@ -FROM dunglas/frankenphp +FROM dunglas/frankenphp:1.1.5-php8 as base ARG UPDATE_DATE ARG DEBIAN_FRONTEND=noninteractive SHELL ["/bin/bash", "-exo", "pipefail", "-c"] +# hadolint ignore=DL3008 RUN \ set -exo pipefail ;\ apt-get update ;\ apt-get upgrade -y ;\ apt-get install -y -q --no-install-recommends \ git \ + unzip \ ;\ install-php-extensions \ - zip \ opcache \ ;\ curl -sS https://getcomposer.org/installer | \ @@ -20,21 +21,15 @@ RUN \ ;\ apt-get clean autoclean ;\ apt-get autoremove -y --allow-remove-essential ;\ - apt-get autoremove apt --autoremove -y --allow-remove-essential ;\ - rm -rf \ + apt-get autoremove apt --autoremove -y --allow-remove-essential ;\rm -rf \ /var/lib/{apt,dpkg,cache,log}/ /tmp/* /var/tmp/* \ - /var/cache/apt/archives /usr/share/{doc,man,locale}/ - + /var/cache/apt/archives /usr/share/{doc,man,locale} RUN chown www-data:www-data /app USER www-data -COPY --chown=www-data:www-data composer.* /app -RUN composer install - -COPY --chown=www-data:www-data . /app - ONBUILD ARG USER=www-data ONBUILD USER root +# hadolint ignore=SC3010 ONBUILD RUN \ if [[ "${USER}" != "www-data" ]]; then \ useradd -M "${USER}" ;\ @@ -45,3 +40,47 @@ ONBUILD RUN \ chown -R "${USER}:${USER}" /config/caddy ;\ fi ONBUILD USER ${USER} + +################################################################################### +# STAGE prepare-binary-env +################################################################################### +FROM base as prepare-binary-env + +SHELL ["/bin/bash", "-exo", "pipefail", "-c"] + +COPY --chown=www-data:www-data composer.* /app +RUN composer install + +COPY --chown=www-data:www-data . /app +RUN \ + # Set proper environment variables + echo APP_ENV=prod > .env.local ;\ + echo APP_DEBUG=0 >> .env.local ;\ + \ + # Remove the tests and other unneeded files to save space + # Alternatively, add these files with the export-ignore attribute + # in your .gitattributes file + rm -Rf tests/ config-generated/ ;\ + \ + # Install the dependencies + composer install --ignore-platform-reqs --no-dev -a ;\ + \ + # Optimize .env + composer config --no-plugins allow-plugins.symfony/flex true ;\ + composer require symfony/flex ;\ + composer require symfony/dotenv ;\ + composer dump-env prod + +################################################################################### +# STAGE build-bin-file +################################################################################### +FROM dunglas/frankenphp:static-builder-1.1 as build-bin-file + +SHELL ["/bin/bash", "-exo", "pipefail", "-c"] + +WORKDIR /go/src/app/dist/app +COPY --from=prepare-binary-env /app . + +# Build the static binary +WORKDIR /go/src/app/ +RUN EMBED=dist/app/ ./build-static.sh