From 439378828bc49313451b78e5e3a4092f0159a695 Mon Sep 17 00:00:00 2001 From: 0x1026 <69076992+0x1026@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:10:04 +0100 Subject: [PATCH 1/5] test: replace docblock with attribute to indicate test coverage --- tests/Feature/ExampleTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 908d229b..d06200ac 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -2,13 +2,12 @@ namespace Tests\Feature; +use PHPUnit\Framework\Attributes\CoversNothing; use Tests\TestCase; class ExampleTest extends TestCase { - /** - * A basic test example. - */ + #[CoversNothing] public function test_that_true_is_true(): void { $this->assertTrue(true); From 36cd5554ebe38765028596f9d377ae0bce8a0058 Mon Sep 17 00:00:00 2001 From: 0x1026 <69076992+0x1026@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:10:34 +0100 Subject: [PATCH 2/5] chore(deps): update phpunit version to 11.4.4 in composer.json and regenerate composer.lock --- composer.json | 2 +- composer.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index b1de73e2..846f4302 100755 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ } ], "require-dev": { - "phpunit/phpunit": "^11.4" + "phpunit/phpunit": "11.4.4" }, "require": { "php": "^8.2" diff --git a/composer.lock b/composer.lock index 15af18cc..179cdb44 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b21def71c8981236ca1d456601161b39", + "content-hash": "c0cdd15c20ca9890d7a0ccb9d759bd07", "packages": [], "packages-dev": [ { @@ -1642,12 +1642,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } From 3be70767a5dfcdaf16736061bc4664b63e5033dc Mon Sep 17 00:00:00 2001 From: 0x1026 <69076992+0x1026@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:11:43 +0100 Subject: [PATCH 3/5] feat(db-env): add dev env variables and port to the database connection string --- .env.example | 9 ++++++++- src/app/Core/Database.php | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index d3e48e0b..a1fb16dc 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,12 @@ APP_NAME=Urban Tree 5.0 -DB_HOST=database + +ENV=development + +#* Database + DB_NAME=urbantree DB_USER=root DB_PASS=J0HMXAJ6XE +# If you are using docker-compose, you can ignore the following variables +DB_HOST=database +DB_PORT=3306 diff --git a/src/app/Core/Database.php b/src/app/Core/Database.php index 02b3bf30..330697e6 100755 --- a/src/app/Core/Database.php +++ b/src/app/Core/Database.php @@ -19,7 +19,7 @@ public static function connect() trim(file_get_contents(getenv('DB_PASS_FILE_PATH'))); self::$instance = new PDO( - 'mysql:host='.getenv('DB_HOST').';dbname='.getenv('DB_NAME'), + 'mysql:host='.getenv('DB_HOST').';port='.getenv('DB_PORT').';dbname='.getenv('DB_NAME'), getenv('DB_USER'), $db_pass ); From 7c9fff4ccf4010f541fb77d4f323d573eff901e6 Mon Sep 17 00:00:00 2001 From: 0x1026 <69076992+0x1026@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:12:08 +0100 Subject: [PATCH 4/5] chore(tests): update phpunit configuration for stricter coverage and execution settings --- phpunit.xml.dist | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 311b87d5..93096429 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,6 +2,16 @@ @@ -12,13 +22,15 @@ tests/Feature + - app + src + - + \ No newline at end of file From a6dd6180b6a2df8e512ee683f0cddf450bafe174 Mon Sep 17 00:00:00 2001 From: 0x1026 <69076992+0x1026@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:12:24 +0100 Subject: [PATCH 5/5] feat(ci): rename Docker workflow to main.yml and restructure CI/CD jobs --- .github/workflows/{docker.yml => main.yml} | 60 ++++++++++++---------- .github/workflows/tests.yml | 51 ++++++++++++++++++ 2 files changed, 85 insertions(+), 26 deletions(-) rename .github/workflows/{docker.yml => main.yml} (70%) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/main.yml similarity index 70% rename from .github/workflows/docker.yml rename to .github/workflows/main.yml index 9e3858d8..0c4e6d14 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/main.yml @@ -3,22 +3,34 @@ # separate terms of service, privacy policy, and support # documentation. -name: ๐Ÿณ Docker CI/CD +name: ๐ŸŒณ CI/CD on: push: branches: ["main"] - tags: ["v*.*.*"] + tags: ["v*"] pull_request: - branches: ["main"] env: REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} jobs: + tests: + name: ๐Ÿงช Tests + uses: ./.github/workflows/tests.yml + secrets: inherit + build: - name: ๐Ÿ—๏ธ Build and push Docker image + name: ๐Ÿณ Docker runs-on: ubuntu-latest + needs: tests + strategy: + fail-fast: false + # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow#example-adding-configurations + matrix: + image: [urbantree] + include: + - image: urbantree + context: . permissions: contents: read packages: write @@ -28,18 +40,19 @@ jobs: id-token: write steps: + # https://github.com/actions/checkout/tree/11bd71901bbe5b1630ceea73d27597364c9af683 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - # https://github.com/sigstore/cosign-installer + # https://github.com/sigstore/cosign-installer/tree/dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da - uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da if: github.event_name != 'pull_request' with: cosign-release: "v2.2.4" - # https://github.com/docker/setup-buildx-action + # https://github.com/docker/setup-buildx-action/tree/c47758b77c9736f4b2ef4073d4d51994fabfe349 - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 - # https://github.com/docker/login-action + # https://github.com/docker/login-action/tree/7ca345011ac4304463197fac0e56eab1bc7e6af0 - name: ๐Ÿชช Log into registry ${{ env.REGISTRY }} uses: docker/login-action@7ca345011ac4304463197fac0e56eab1bc7e6af0 if: github.event_name != 'pull_request' @@ -48,11 +61,11 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # https://github.com/docker/metadata-action + # https://github.com/docker/metadata-action/tree/b53be03109c4ef6f6cc7aa545b84b17a7fe51c1e - uses: docker/metadata-action@b53be03109c4ef6f6cc7aa545b84b17a7fe51c1e id: meta with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.image }} tags: | type=ref,event=branch type=ref,event=pr @@ -61,37 +74,30 @@ jobs: env: DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,manifest-descriptor,index,index-descriptor + # https://github.com/actions/cache/tree/6849a6489940f00c2f30c0fb92c6274307ccb58a - name: ๐Ÿ“ฆ Cache Docker layers uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a with: - path: tmp-cache + path: | + composer-cache key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile') }} + # https://github.com/reproducible-containers/buildkit-cache-dance/tree/5b6db76d1da5c8b307d5d2e0706d266521b710de - name: ๐Ÿ“ฆ Load cache uses: reproducible-containers/buildkit-cache-dance@5b6db76d1da5c8b307d5d2e0706d266521b710de with: cache-map: | { - "tmp-cache": "/tmp/cache" + "composer-cache": "/tmp/cache" } skip-extraction: ${{ steps.cache.outputs.cache-hit }} - # https://github.com/docker/build-push-action - - name: ๐Ÿงช Tests - uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 - with: - context: . - target: test - load: true - cache-from: type=gha - cache-to: type=gha,mode=max - - # https://github.com/docker/build-push-action + # https://github.com/docker/build-push-action/tree/48aba3b46d1b1fec4febb7c5d0c644b249a11355 - name: ๐Ÿ—๏ธ Build final stage and push to ${{ env.REGISTRY }} id: build-and-push uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 with: - context: . + context: ${{ matrix.context }} push: ${{ github.event_name != 'pull_request' }} target: final tags: ${{ steps.meta.outputs.tags }} @@ -115,11 +121,12 @@ jobs: # against the sigstore community Fulcio instance. run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} + # https://github.com/actions/attest-build-provenance/tree/ef244123eb79f2f7a7e75d99086184180e6d0018 - name: ๐Ÿ“ Attest the build provenance - uses: actions/attest-build-provenance@v1 + uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 if: ${{ github.event_name != 'pull_request' }} with: - subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + subject-name: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.image }} subject-digest: ${{ steps.build-and-push.outputs.digest }} push-to-registry: true @@ -130,6 +137,7 @@ jobs: if: ${{ github.event_name != 'pull_request' }} steps: + # https://github.com/appleboy/ssh-action/tree/7eaf76671a0d7eec5d98ee897acda4f968735a17 - name: ๐Ÿšš SSH into production server uses: appleboy/ssh-action@7eaf76671a0d7eec5d98ee897acda4f968735a17 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..3033a731 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,51 @@ +name: ๐Ÿงช Tests + +on: + workflow_call: + +jobs: + urbantree: + name: ๐Ÿงช UrbanTree + runs-on: ubuntu-latest + steps: + # https://github.com/actions/checkout/tree/11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + # https://github.com/actions/cache/tree/6849a6489940f00c2f30c0fb92c6274307ccb58a + - name: ๐Ÿ“ฆ Cache Composer dependencies + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a + with: + path: /tmp/composer-cache + key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} + + # https://github.com/shivammathur/setup-php/tree/c541c155eee45413f5b09a52248675b1a2575231 + - name: ๐Ÿ˜ Setup PHP with extensions + uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 + with: + php-version: 8.4 + coverage: xdebug + extensions: none, ctype, curl, dom, json, libxml, mbstring, pdo, phar, tokenizer, xml, xmlwriter + ini-values: zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On + tools: none + + # https://github.com/php-actions/composer/tree/8a65f0d3c6a1d17ca4800491a40b5756a4c164f3 + - name: ๐Ÿ“ฆ Install Composer dependencies + uses: php-actions/composer@8a65f0d3c6a1d17ca4800491a40b5756a4c164f3 + + - name: ๐Ÿงช Run PHPUnit tests with coverage + shell: bash + run: ./vendor/bin/phpunit --log-junit junit.xml --coverage-clover=coverage.xml + + # https://github.com/codecov/test-results-action/tree/9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 + - name: ๐Ÿ“Š Upload test results to Codecov + if: ${{ !cancelled() }} + uses: codecov/test-results-action@9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # https://github.com/codecov/codecov-action/tree/015f24e6818733317a2da2edd6290ab26238649a + - name: Upload coverage to Codecov + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a + with: + verbose: true + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}