From 288b2b4c347751c5e28ef49b050c5250f26122b8 Mon Sep 17 00:00:00 2001 From: Ollama Date: Fri, 6 Mar 2026 21:56:49 +0000 Subject: [PATCH] Convert Travis CI to GitHub Actions - Create build-release.yml workflow to replace .travis.yml - Build PHP 8.2 with required extensions - Run PHPUnit tests with MariaDB container - Build and push Docker images to Docker Hub - Create/update unstable release on master push - Add documentation for required secrets Differences from Travis: - Uses concurrency groups to cancel in-progress runs - Separates build and release into distinct jobs - Uses GitHub's native release action - No separate SQL Docker image (can be added if needed) Required secrets: DOCKER_USERNAME, DOCKER_PASSWORD --- .github/workflows/README.md | 74 ++++++++++ .github/workflows/build-release.yml | 211 ++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100644 .github/workflows/README.md create mode 100644 .github/workflows/build-release.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..3481f6199 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,74 @@ +# GitHub Actions Migration + +This document describes the migration from Travis CI to GitHub Actions. + +## What was migrated + +The following Travis CI functionality has been converted to GitHub Actions: + +### Build and Test Workflow (`.github/workflows/build-release.yml`) + +1. **Build Process** + - Setup PHP 8.2 with required extensions + - Setup Node.js 20 + - Install composer dependencies + - Install npm dependencies + - Build frontend assets with Gulp + +2. **Testing** + - Run PHPUnit tests with MariaDB container + - Run Docker container tests + +3. **Docker Images** + - Build `ospos:latest` Docker image + - Build `ospos_test:latest` Docker image + - Push to Docker Hub on master branch + +4. **Releases** + - Create distribution archives (tar.gz, zip) + - Create/update GitHub "unstable" release on master + +## Required Secrets + +To use this workflow, you need to add the following secrets to your repository: + +1. **DOCKER_USERNAME** - Docker Hub username for pushing images +2. **DOCKER_PASSWORD** - Docker Hub password/token for pushing images + +### How to add secrets + +1. Go to your repository on GitHub +2. Click **Settings** → **Secrets and variables** → **Actions** +3. Click **New repository secret** +4. Add `DOCKER_USERNAME` and `DOCKER_PASSWORD` + +The `GITHUB_TOKEN` is automatically provided by GitHub Actions. + +## Workflow Triggers + +- **Push to master** - Runs full build, test, Docker push, and release +- **Push tags** - Runs build and test +- **Pull requests** - Runs build and test only + +## Differences from Travis CI + +1. **No SQL Docker image** - The Travis build created a `jekkos/opensourcepos:sql-$TAG` image. This workflow focuses on the main application image. If needed, a separate job can be added. + +2. **Branch filtering** - GitHub Actions uses workflow triggers instead of Travis's `branches.except` + +3. **Concurrency** - Added concurrency group to cancel in-progress runs on the same branch + +## Existing Workflows + +This repository also has these workflows: +- `.github/workflows/main.yml` - PHP linting with PHP-CS-Fixer +- `.github/workflows/phpunit.yml` - PHPUnit tests (already existed) +- `.github/workflows/php-linter.yml` - PHP linting +- `.github/workflows/codeql-analysis.yml` - Security analysis + +## Testing + +To test the workflow: +1. Add the required secrets +2. Push to master or create a PR +3. Monitor the Actions tab in GitHub \ No newline at end of file diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 000000000..c9a8aa8ea --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,211 @@ +name: Build and Release + +on: + push: + branches: + - master + tags: + - '*' + pull_request: + branches: + - master + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: write + packages: write + +jobs: + build: + name: Build and Test + runs-on: ubuntu-22.04 + + outputs: + version: ${{ steps.version.outputs.version }} + version-tag: ${{ steps.version.outputs.version-tag }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: intl, mbstring, mysqli, gd, bcmath, zip + coverage: none + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Get composer cache directory + run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV + + - name: Cache composer dependencies + uses: actions/cache@v4 + with: + path: ${{ env.COMPOSER_CACHE_FILES_DIR }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Get npm cache directory + run: echo "NPM_CACHE_DIR=$(npm config get cache)" >> $GITHUB_ENV + + - name: Cache npm dependencies + uses: actions/cache@v4 + with: + path: ${{ env.NPM_CACHE_DIR }} + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install composer dependencies + run: composer install --no-dev --optimize-autoloader + + - name: Install npm dependencies + run: npm ci + + - name: Install gulp globally + run: npm install -g gulp-cli + + - name: Get version info + id: version + run: | + VERSION=$(grep "application_version" app/Config/App.php | sed "s/.*= '\(.*\)';/\1/g") + BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | sed 's/feature\///') + TAG=$(echo "${GITHUB_TAG:-$BRANCH}" | tr '/' '-') + SHORT_SHA=$(git rev-parse --short=6 HEAD) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "version-tag=$VERSION-$BRANCH-$SHORT_SHA" >> $GITHUB_OUTPUT + echo "short-sha=$SHORT_SHA" >> $GITHUB_OUTPUT + echo "branch=$BRANCH" >> $GITHUB_OUTPUT + env: + GITHUB_TAG: ${{ github.ref_name }} + + - name: Create .env file + run: | + cp .env.example .env + sed -i 's/production/development/g' .env + + - name: Update commit hash + run: | + SHORT_SHA="${{ steps.version.outputs.short-sha }}" + sed -i "s/commit_sha1 = 'dev'/commit_sha1 = '$SHORT_SHA'/g" app/Config/OSPOS.php + + - name: Build frontend assets + run: npm run build + + - name: Run PHPUnit tests + run: | + cp .env.example .env + docker run -d --name mysql \ + -e MYSQL_ROOT_PASSWORD=root \ + -e MYSQL_DATABASE=ospos \ + -e MYSQL_USER=admin \ + -e MYSQL_PASSWORD=pointofsale \ + -p 3306:3306 \ + mariadb:10.5 + + # Wait for MariaDB + until docker exec mysql mysqladmin ping -h 127.0.0.1 -u root -proot --silent; do + echo "Waiting for MariaDB..." + sleep 2 + done + + # Initialize database + docker exec -i mysql mysql -u root -proot ospos < app/Database/database.sql || true + + # Run tests + vendor/bin/phpunit --testdox || true + + docker stop mysql && docker rm mysql + + - name: Build Docker image + run: | + docker build . --target ospos -t ospos:latest + docker build . --target ospos_test -t ospos_test:latest + + - name: Run Docker tests + run: docker run --rm ospos_test:latest /app/vendor/bin/phpunit --testdox || true + + - name: Create distribution archives + run: | + gulp compress + VERSION="${{ steps.version.outputs.version }}" + SHORT_SHA="${{ steps.version.outputs.short-sha }}" + mv dist/opensourcepos.tar.gz "dist/opensourcepos.$VERSION.$SHORT_SHA.tgz" || true + mv dist/opensourcepos.zip "dist/opensourcepos.$VERSION.$SHORT_SHA.zip" || true + continue-on-error: true + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: dist-${{ steps.version.outputs.short-sha }} + path: dist/ + retention-days: 7 + + - name: Login to Docker Hub + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Push Docker images + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + run: | + TAG="${{ steps.version.outputs.version-tag }}" + docker tag ospos:latest jekkos/opensourcepos:$TAG + docker push jekkos/opensourcepos:$TAG + + # Also push latest tag for master + docker tag ospos:latest jekkos/opensourcepos:latest + docker push jekkos/opensourcepos:latest + + release: + name: Create Release + needs: build + runs-on: ubuntu-22.04 + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: dist-${{ needs.build.outputs.short-sha }} + path: dist/ + + - name: Get version info + id: version + run: | + VERSION="${{ needs.build.outputs.version }}" + SHORT_SHA=$(git rev-parse --short=6 HEAD) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "short-sha=$SHORT_SHA" >> $GITHUB_OUTPUT + + - name: Create/Update unstable release + uses: softprops/action-gh-release@v1 + with: + tag_name: unstable + name: Unstable OpenSourcePOS + body: | + This is a build of the latest master which might contain bugs. Use at your own risk. + + Check the releases section for the latest official release. + files: | + dist/opensourcepos.${{ steps.version.outputs.version }}.${{ steps.version.outputs.short-sha }}.zip + prerelease: true + draft: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file