Created
July 30, 2021 08:14
-
-
Save mathiasschopmans/71f9acec69ccfd69a1ea7fb5a3f31e03 to your computer and use it in GitHub Desktop.
GitHub Action to test, build, push & deploy PHP based application
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: CI | |
on: | |
push: | |
branches-ignore: | |
- 'dependabot/**' | |
tags: | |
- 'v*' | |
pull_request: | |
branches-ignore: | |
- 'dependabot/**' | |
workflow_dispatch: | |
jobs: | |
buildImages: | |
name: Build Docker images | |
runs-on: ubuntu-latest | |
steps: | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v1 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v1 | |
- name: Checkout | |
uses: actions/checkout@v2 | |
with: | |
fetch-depth: 10 | |
- name: Prepare build | |
run: | | |
mkdir -p /tmp/docker/buildx | |
git log -n 10 --date=short --format=format:"%C(auto)%h %ad @%al %s" >> web/changelog.txt | |
- name: Setup docker build caches | |
uses: actions/cache@v2 | |
with: | |
key: ${{ runner.os }}-buildx | |
path: /tmp/docker/buildx | |
- name: Login to DockerHub | |
uses: docker/login-action@v1 | |
with: | |
username: ${{ secrets.DOCKERHUB_USERNAME }} | |
password: ${{ secrets.DOCKERHUB_PASSWORD }} | |
# Production image | |
- name: Get Docker meta for production image | |
id: meta | |
uses: docker/metadata-action@v3 | |
with: | |
images: mathiasschopmans/app-id | |
tags: | | |
type=sha | |
type=ref,event=branch | |
type=semver,pattern={{version}} | |
type=semver,pattern={{major}}.{{minor}} | |
type=edge,branch=master | |
- name: Build and push production image | |
id: build_latest | |
uses: docker/build-push-action@v2 | |
with: | |
context: . | |
push: false | |
tags: ${{ steps.meta.outputs.tags }} | |
labels: ${{ steps.meta.outputs.labels }} | |
cache-from: | | |
mathiasschopmans/app-id:edge | |
type=local,src=/tmp/docker/buildx | |
cache-to: type=local,dest=/tmp/docker/buildx | |
outputs: type=docker,dest=/tmp/docker/app.tar | |
# Development image | |
- name: Get Docker meta for development | |
id: devmeta | |
uses: docker/metadata-action@v3 | |
with: | |
images: mathiasschopmans/app-id | |
flavor: | | |
suffix=-dev | |
tags: | | |
type=sha | |
type=ref,event=branch | |
- name: Build and push development image | |
id: build_dev | |
uses: docker/build-push-action@v2 | |
with: | |
file: Dockerfile | |
push: false | |
tags: ${{ steps.devmeta.outputs.tags }} | |
labels: ${{ steps.devmeta.outputs.labels }} | |
build-args: | | |
BUILD_DEV="true" | |
cache-from: | | |
mathiasschopmans/app-id:edge-dev | |
type=local,src=/tmp/docker/buildx | |
cache-to: type=local,dest=/tmp/docker/buildx | |
outputs: type=docker,dest=/tmp/docker/dev.tar | |
# Upload artifacts | |
- name: Upload docker images | |
uses: actions/upload-artifact@v2 | |
with: | |
name: docker-images | |
path: /tmp/docker/*.tar | |
outputs: | |
image: ${{ fromJSON(steps.meta.outputs.json).tags[0] }} | |
images: ${{ join(steps.meta.outputs.tags, ' ') }} | |
imageDev: ${{ fromJSON(steps.devmeta.outputs.json).tags[0] }} | |
imagesDev: ${{ join(steps.devmeta.outputs.tags, ' ') }} | |
testUnitFunctional: | |
name: Run unit- and functional-tests | |
needs: [ buildImages ] | |
runs-on: ubuntu-latest | |
env: | |
SERVICE: app # use `dev` to enable xdebug and code coverage | |
IMAGE_APP: ${{ needs.buildImages.outputs.image }} | |
IMAGE_DEV: ${{ needs.buildImages.outputs.imageDev }} | |
COMPOSE_INTERACTIVE_NO_CLI: true | |
steps: | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v1 | |
- uses: actions/checkout@v2 | |
- name: Download docker images | |
uses: actions/download-artifact@v2 | |
with: | |
name: docker-images | |
path: /tmp/docker | |
- name: Import docker image | |
run: | | |
docker load --input /tmp/docker/app.tar | |
docker load --input /tmp/docker/dev.tar | |
docker image ls -a | grep aoepeople | |
- name: Test with docker compose | |
run: | | |
docker-compose pull db | |
docker-compose up -d --no-build db | |
docker-compose up -d $SERVICE | |
sleep 15 | |
docker-compose exec -T $SERVICE composer install | |
docker-compose exec -T $SERVICE app/console doctrine:schema:update --env=test --force | |
docker-compose exec -T $SERVICE mkdir -p app/build/logs/ | |
docker-compose exec -T $SERVICE bin/phpunit -d memory_limit=-1 -c app/config/commons/development/phpunit.xml | |
docker-compose exec -T $SERVICE bash -c "find app/build -type f -regex '.*\.\(html\|xml\)' | xargs sed -i 's#/var/www/html/##g'" | |
docker-compose down -v --remove-orphans | |
- name: Upload coverage report artifact | |
uses: actions/[email protected] | |
if: always() | |
with: | |
name: reports | |
path: app/build/ | |
- name: Publish unit-test results | |
uses: mikepenz/action-junit-report@v2 | |
if: always() | |
with: | |
report_paths: 'app/build/logs/*.xml' | |
lint: | |
name: Lint code | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v2 | |
- uses: actions/setup-node@v2 | |
with: | |
node-version: '14' | |
- name: Cache node_modules | |
uses: actions/cache@v2 | |
with: | |
path: '**/node_modules' | |
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} | |
- name: Install npm packages | |
working-directory: ./app/Resources | |
run: yarn install | |
- name: Run FE linters | |
working-directory: ./app/Resources | |
run: yarn lint | |
phpmd: | |
name: PHPMD | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v2 | |
- name: Setup PHP environment | |
uses: shivammathur/setup-php@v2 | |
with: | |
coverage: none | |
tools: phpmd | |
- name: Run PHPMD | |
run: phpmd src github ./app/config/commons/development/phpmd.xml --baseline-file ./phpmd.baseline.xml | |
snyk: | |
name: Scan vulnerabilities | |
if: ${{ github.ref == 'refs/heads/master' }} | |
needs: [ buildImages ] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v2 | |
- name: Run Snyk to check Docker image for vulnerabilities | |
# Snyk can be used to break the build when it detects vulnerabilities. | |
# In this case we want to upload the issues to GitHub Code Scanning | |
continue-on-error: true | |
uses: snyk/actions/docker@master | |
env: | |
# In order to use the Snyk Action you will need to have a Snyk API token. | |
# More details in https://github.com/snyk/actions#getting-your-snyk-token | |
# or you can signup for free at https://snyk.io/login | |
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
with: | |
image: ${{ needs.buildImages.outputs.image }} | |
args: --file=Dockerfile | |
- name: Upload result to GitHub Code Scanning | |
uses: github/codeql-action/upload-sarif@v1 | |
with: | |
sarif_file: snyk.sarif | |
publish: | |
name: Publish | |
if: ${{ github.ref == 'refs/heads/master' }} | |
needs: [ buildImages, testUnitFunctional, snyk ] | |
runs-on: ubuntu-latest | |
env: | |
IMAGES_APP: ${{ needs.buildImages.outputs.images }} | |
IMAGES_DEV: ${{ needs.buildImages.outputs.imagesDev }} | |
steps: | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v1 | |
- name: Login to DockerHub | |
uses: docker/login-action@v1 | |
with: | |
username: ${{ secrets.DOCKERHUB_USERNAME }} | |
password: ${{ secrets.DOCKERHUB_PASSWORD }} | |
- name: Download docker images | |
uses: actions/download-artifact@v2 | |
with: | |
name: docker-images | |
path: /tmp/docker | |
- name: Import docker image | |
run: | | |
docker load --input /tmp/docker/app.tar | |
docker load --input /tmp/docker/dev.tar | |
docker image ls -a | grep aoepeople | |
- name: Deploy images | |
run: | | |
for tag in $IMAGES_APP; do | |
if [[ $tag = *sha-* ]]; then | |
continue; | |
fi | |
docker push $tag; | |
done | |
for tag in $IMAGES_DEV; do | |
if [[ $tag = *sha-* ]]; then | |
continue; | |
fi | |
docker push $tag; | |
done | |
- name: Delete docker image artifact | |
uses: geekyeggo/delete-artifact@v1 | |
with: | |
name: docker-images | |
deploy: | |
name: Deploy and notify | |
if: ${{ github.ref == 'refs/heads/master' }} | |
needs: [ publish ] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Deploy to staging environment | |
env: | |
IMAGE: ${{ needs.buildImages.outputs.image }} | |
GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }} | |
run: | | |
curl -X POST \ | |
-F "ref=master" \ | |
-F "variables[IMAGE]=$IMAGE" \ | |
-F "variables[GITHUB_SHA]=$GITHUB_SHA" \ | |
-F "token=$GITLAB_TRIGGER_TOKEN" \ | |
https://gitlab.aoe.com/api/v4/projects/111111/trigger/pipeline | |
- name: Notify team | |
env: | |
COMMIT_MSG: ${{ github.event.head_commit.message }} | |
MATTERMOST_HOOK_URL: ${{ secrets.MATTERMOST_HOOK_URL }} | |
run: | | |
curl --silent -i -X POST -H 'Content-Type: application/json' \ | |
-d '{"text": "Triggered deployment of `meals-staging.aoe.com@'"$GITHUB_SHA"'`\n> '"$COMMIT_MSG"'"}' \ | |
$MATTERMOST_HOOK_URL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment