Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Making Things Happen With Make

Making Things Happen With Make

#phptek 2023

Joe Ferguson

May 23, 2023
Tweet

More Decks by Joe Ferguson

Other Decks in Programming

Transcript

  1. Joe Ferguson Principal Software Engineer @ Preteckt Open Source Geek

    OSMI fanboi ⚽,🏒, and 🏎 fan Twitter: @JoePFerguson
  2. `$ man make` 📚 DESCRIPTION The purpose of the make

    utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them.
  3. Compile a simple C application with make foo: foo.c cc

    foo.c -o foo // foo.c int main() { return 0; }
  4. Make for PHP developers Part 1 - composer.json "scripts": {

    "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi", "@php artisan vendor:publish --force --tag=livewire:assets --ansi" ], "post-create-project-cmd": [ "php artisan key:generate" ] },
  5. Make for PHP developers Part 2 package.json "scripts": { "dev":

    "npm run development", "development": "mix", "watch": "mix watch", "watch-poll": "mix watch -- --watch-options-poll=1000", "hot": "mix watch --hot", "prod": "npm run production", "production": "mix --production" },
  6. How do you setup your development environment? $ cp .env.example

    .env $ composer install # must be tab indent $ npm install $ npm run development $ mysql -u root -e "CREATE DATABASE IF NOT EXISTS app;" $ php artisan key:generate $ php artisan migrate
  7. Enter our Makefile .DEFAULT_GOAL := setup # make by itself

    will run setup .PHONY: setup setup: # this is the target cp .env.example .env # must be tab indent composer install # there are no PSRs here npm install php artisan key:generate php artisan migrate
  8. Build our initial Makefile in the project root .DEFAULT_GOAL :=

    setup .PHONY: setup setup: cp .env.example .env composer install npm install npm run development php artisan key:generate php artisan migrate .PHONY: clean clean: rm -rf vendor/ rm -rf node_modules/
  9. Adding a target to clean our database .PHONY: clean_db clean_db:

    php artisan migrate:fresh php artisan db:seed
  10. Making strings and things SHELL := /bin/bash PROJECT_DIR := $(shell

    dirname $(realpath $(lastword $(MAKEFILE_LIST)))) PROJECT_NAME = build_things_get_paid PYTHON_INTERPRETER= python3.11 ENV_DIR = env
  11. Clean up files wherever they may be in the project

    clean: find . -type f -name "*.py[co]" -delete find . -type d -name "__pycache__" -delete
  12. Adding Variables to our Makefile REGISTRY := registry.phparch.com REPOSITORY :=

    svpernova09/snipe-it BUILD = DOCKER_BUILDKIT=1 docker build .DEFAULT_GOAL := setup
  13. Adding Variables to our Makefile .DEFAULT_GOAL := setup .PHONY: docker_build

    docker_build: $(BUILD) -t $(REGISTRY)/$(REPOSITORY):latest -f Dockerfile .
  14. We’re using variables for string concatenation DOCKER_BUILDKIT=1 docker build -t

    registry.phparch.com/svpernova09/snipe-it:latest -f Dockerfile .
  15. Build Multiple Images .PHONY: docker_build_alpine docker_build_alpine: $(BUILD) -t $(REGISTRY)/$(REPOSITORY)-alpine:latest -f

    Dockerfile.alpine . .PHONY: docker_build_alpine_fpm docker_build_alpine_fpm: $(BUILD) -t $(REGISTRY)/$(REPOSITORY)-fpm-alpine:latest -f Dockerfile.fpm-alpine .
  16. Reuse targets to chain them together .PHONY: docker_build_all docker_build_all: |

    docker_build docker_build_alpine docker_build_alpine_fpm
  17. Don’t forget to publish them to your registry .PHONY: docker_push_all

    docker_push: docker push $(REGISTRY)/$(REPOSITORY):latest docker push $(REGISTRY)/$(REPOSITORY)-alpine:latest docker push $(REGISTRY)/$(REPOSITORY)-fpm-alpine:latest
  18. Use a known value for your build images BUILD =

    DOCKER_BUILDKIT=1 docker build ifndef GITHUB_RUN_ID GITHUB_RUN_ID=latest endif .DEFAULT_GOAL := setup
  19. Allows us to be more flexible in our tags .PHONY:

    docker_push_all docker_push: docker push $(REGISTRY)/$(REPOSITORY):$(GITHUB_RUN_ID) docker push $(REGISTRY)/$(REPOSITORY)-alpine:$(GITHUB_RUN_ID) docker push $(REGISTRY)/$(REPOSITORY)-fpm-alpine:$(GITHUB_RUN_ID)
  20. Typical configuration to set up our app and run tests

    name: PHP App on: [push, pull_request] jobs: build: runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: php: ['8.1'] name: PHP ${{ matrix.php }} services: mysql: image: mysql:5.7 env: MYSQL_ALLOW_EMPTY_PASSWORD: yes MYSQL_DATABASE: app ports: - 3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
  21. Typical configuration to set up our app and run tests

    steps: - name: Checkout Code uses: actions/checkout@v1 - name: Setup PHP uses: shivammathur/[email protected] with: php-version: ${{ matrix.php }} extensions: dom, curl, libxml, mbstring - name: Copy Env run: cp .env.example .env - name: Install dependencies & Setup App run: | composer install && php artisan key:generate --ansi && php artisan migrate --force && php artisan db:seed --force env: DB_PORT: ${{ job.services.mysql.ports[3306] }}
  22. Run the tests! - name: Run the tests run: vendor/bin/phpunit

    env: DB_PORT: ${{ job.services.mysql.ports[3306] }}
  23. Replace commands with our make targets steps: - name: Checkout

    Code uses: actions/checkout@v1 - name: Setup PHP uses: shivammathur/[email protected] with: php-version: ${{ matrix.php }} extensions: dom, curl, libxml, mbstring, zip, pcntl, ... coverage: none - name: Install dependencies & Setup App run: make setup env: DB_PORT: ${{ job.services.mysql.ports[3306] }} - name: Run tests run: make test env: DB_PORT: ${{ job.services.mysql.ports[3306] }}
  24. Adding our SSH key to Secrets for Deployments - name:

    Install SSH key uses: shimataro/ssh-key-action@v2 with: key: ${{ secrets.SSH_KEY }} known_hosts: ${{ secrets.KNOWN_HOSTS }} if: github.ref == 'refs/heads/master' - name: Deploy run: make deploy if: github.ref == 'refs/heads/master'