From 8b7eb9447f0d2bd783009a78f3822bc666ec459f Mon Sep 17 00:00:00 2001 From: digikwal Date: Tue, 24 Jun 2025 18:28:55 +0200 Subject: [PATCH] ci: add semantic-release, docker build & pre-commit workflows --- .github/workflows/build_bench.yml | 59 ---------- .github/workflows/build_develop.yml | 33 ------ .github/workflows/build_stable.yml | 116 -------------------- .github/workflows/docker-build-push.yml | 101 ----------------- .github/workflows/docker-build.yml | 64 +++++++++++ .github/workflows/lint.yml | 10 +- .github/workflows/pre-commit-autoupdate.yml | 26 ++++- .github/workflows/semantic-release.yml | 60 ++++++++++ .github/workflows/stale.yml | 10 +- 9 files changed, 161 insertions(+), 318 deletions(-) delete mode 100644 .github/workflows/build_bench.yml delete mode 100644 .github/workflows/build_develop.yml delete mode 100644 .github/workflows/build_stable.yml delete mode 100644 .github/workflows/docker-build-push.yml create mode 100644 .github/workflows/docker-build.yml create mode 100644 .github/workflows/semantic-release.yml diff --git a/.github/workflows/build_bench.yml b/.github/workflows/build_bench.yml deleted file mode 100644 index e5a61141..00000000 --- a/.github/workflows/build_bench.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Bench - -on: - pull_request: - branches: - - main - paths: - - images/bench/** - - docker-bake.hcl - - .github/workflows/build_bench.yml - - schedule: - # Every day at 12:00 pm - - cron: 0 0 * * * - - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:latest - platforms: all - - - name: Setup Buildx - uses: docker/setup-buildx-action@v3 - - - name: Set Environment Variables - run: cat example.env | grep -o '^[^#]*' >> "$GITHUB_ENV" - - - name: Get Bench Latest Version - run: echo "LATEST_BENCH_RELEASE=$(curl -s 'https://api.github.com/repos/frappe/bench/releases/latest' | jq -r '.tag_name')" >> "$GITHUB_ENV" - - - name: Build and test - uses: docker/bake-action@v6.8.0 - with: - source: . - targets: bench-test - - - name: Login - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Push - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - uses: docker/bake-action@v6.8.0 - with: - targets: bench - push: true - set: "*.platform=linux/amd64,linux/arm64" diff --git a/.github/workflows/build_develop.yml b/.github/workflows/build_develop.yml deleted file mode 100644 index e37c5858..00000000 --- a/.github/workflows/build_develop.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Develop build - -on: - pull_request: - branches: - - main - paths: - - images/production/** - - overrides/** - - tests/** - - compose.yaml - - docker-bake.hcl - - example.env - - .github/workflows/build_develop.yml - - schedule: - # Every day at 12:00 pm - - cron: 0 0 * * * - - workflow_dispatch: - -jobs: - build: - uses: ./.github/workflows/docker-build-push.yml - with: - repo: erpnext - version: develop - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.11.6 - node_version: 18.18.2 - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml deleted file mode 100644 index 275c22ac..00000000 --- a/.github/workflows/build_stable.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: Stable build - -on: - pull_request: - branches: - - main - paths: - - images/production/** - - overrides/** - - tests/** - - compose.yaml - - docker-bake.hcl - - example.env - - .github/workflows/build_stable.yml - - push: - branches: - - main - paths: - - images/production/** - - overrides/** - - tests/** - - compose.yaml - - docker-bake.hcl - - example.env - - # Triggered from frappe/frappe and frappe/erpnext on releases - repository_dispatch: - - workflow_dispatch: - -jobs: - v14: - uses: ./.github/workflows/docker-build-push.yml - with: - repo: erpnext - version: "14" - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.10.13 - node_version: 16.20.2 - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - - v15: - uses: ./.github/workflows/docker-build-push.yml - with: - repo: erpnext - version: "15" - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - python_version: 3.11.6 - node_version: 20.19.2 - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - - update_versions: - name: Update example.env and pwd.yml - runs-on: ubuntu-latest - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - needs: v15 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Get latest versions - run: python3 ./.github/scripts/get_latest_tags.py --repo erpnext --version 15 - - - name: Update - run: | - python3 ./.github/scripts/update_example_env.py - python3 ./.github/scripts/update_pwd.py - - - name: Push - run: | - git config --global user.name github-actions - git config --global user.email github-actions@github.com - git add example.env pwd.yml - if [ -z "$(git status --porcelain)" ]; then - echo "versions did not change, exiting." - exit 0 - else - echo "version changed, pushing changes..." - git commit -m "chore: Update example.env" - git pull --rebase - git push origin main - fi - - release_helm: - name: Release Helm - runs-on: ubuntu-latest - if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - needs: v15 - - steps: - - name: Setup deploy key - uses: webfactory/ssh-agent@v0.9.1 - with: - ssh-private-key: ${{ secrets.HELM_DEPLOY_KEY }} - - - name: Setup Git Credentials - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - - name: Release - run: | - git clone git@github.com:frappe/helm.git && cd helm - pip install -r release_wizard/requirements.txt - ./release_wizard/wizard 15 patch --remote origin --ci diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml deleted file mode 100644 index 3694ec00..00000000 --- a/.github/workflows/docker-build-push.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Build - -on: - workflow_call: - inputs: - repo: - required: true - type: string - description: "'erpnext' or 'frappe'" - version: - required: true - type: string - description: "Major version, git tags should match 'v{version}.*'; or 'develop'" - push: - required: true - type: boolean - python_version: - required: true - type: string - description: Python Version - node_version: - required: true - type: string - description: NodeJS Version - secrets: - DOCKERHUB_USERNAME: - required: true - DOCKERHUB_TOKEN: - required: true - -jobs: - build: - name: Build - runs-on: ubuntu-latest - services: - registry: - image: docker.io/registry:2 - ports: - - 5000:5000 - strategy: - matrix: - arch: [amd64, arm64] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:latest - platforms: all - - - name: Setup Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: network=host - platforms: linux/${{ matrix.arch }} - - - name: Get latest versions - run: python3 ./.github/scripts/get_latest_tags.py --repo ${{ inputs.repo }} --version ${{ inputs.version }} - - - name: Set build args - run: | - echo "PYTHON_VERSION=${{ inputs.python_version }}" >> "$GITHUB_ENV" - echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV" - - - name: Build - uses: docker/bake-action@v6.8.0 - with: - source: . - push: true - env: - REGISTRY_USER: localhost:5000/frappe - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install dependencies - run: | - python -m venv venv - venv/bin/pip install -r requirements-test.txt - - - name: Test - run: venv/bin/pytest --color=yes - - - name: Login - if: ${{ inputs.push }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Push - if: ${{ inputs.push }} - uses: docker/bake-action@v6.8.0 - with: - push: true - set: "*.platform=linux/amd64,linux/arm64" diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000..7a57d869 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,64 @@ +name: Build and Push ERPNext Docker Image + +on: + workflow_run: + workflows: + - Semantic Release + types: + - completed + +jobs: + build-and-push: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Download release metadata + uses: actions/download-artifact@v4 + with: + name: release-metadata + path: ./artifacts/release-metadata + github-token: ${{ secrets.GITHUB_TOKEN }} + repository: digikwal/frappe_docker + run-id: ${{ github.event.workflow_run.id }} + + - name: Load release metadata + run: | + export RELEASE_TAG=$(cat ./artifacts/release-metadata/release_tag.txt) + export FRAPPE_BRANCH=$(cat ./artifacts/release-metadata/frappe_branch.txt) + echo "RELEASE_TAG=$RELEASE_TAG" >> $GITHUB_ENV + echo "FRAPPE_BRANCH=$FRAPPE_BRANCH" >> $GITHUB_ENV + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PAT }} + + - name: Encode apps.json + run: | + export APPS_JSON_BASE64=$(base64 -w 0 ./apps.json) + echo "APPS_JSON_BASE64=$APPS_JSON_BASE64" >> $GITHUB_ENV + + - name: Build Docker image + run: | + docker build \ + --build-arg FRAPPE_PATH=https://github.com/frappe/frappe \ + --build-arg FRAPPE_BRANCH=${{ env.FRAPPE_BRANCH }} \ + --build-arg APPS_JSON_BASE64=${{ env.APPS_JSON_BASE64 }} \ + --tag digikwal/erpnext:${{ env.RELEASE_TAG }} \ + --file images/layered/Containerfile . + + - name: Push Docker image and tags + run: | + docker push digikwal/erpnext:${{ env.RELEASE_TAG }} + if [[ "${{ env.RELEASE_TAG }}" != *"-"* ]]; then + docker tag digikwal/erpnext:${{ env.RELEASE_TAG }} digikwal/erpnext:latest + docker push digikwal/erpnext:latest + else + docker tag digikwal/erpnext:${{ env.RELEASE_TAG }} digikwal/erpnext:dev + docker push digikwal/erpnext:dev + fi diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ce4ab6ee..9f65e1b7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,12 +4,19 @@ on: push: branches: - main + paths: + - "images/**" + - ".github/workflows/docker-build.yml" pull_request: branches: - main + paths: + - "images/**" + - ".github/workflows/docker-build.yml" jobs: lint: + if: ${{ github.repository == 'digikwal/frappe_docker' }} runs-on: ubuntu-latest steps: - name: Checkout @@ -20,8 +27,7 @@ jobs: with: python-version: "3.10.6" - # For shfmt pre-commit hook - - name: Setup Go + - name: Setup Go (for shfmt) uses: actions/setup-go@v5 with: go-version: "^1.14" diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 5612c735..70916ec9 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -2,18 +2,36 @@ name: Autoupdate pre-commit hooks on: schedule: - # Every day at 7 am - - cron: 0 7 * * * + # Every day at 4 am UTC + - cron: 0 4 * * * jobs: pre-commit-autoupdate: + if: ${{ github.repository == 'digikwal/frappe_docker' }} runs-on: ubuntu-latest + steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + + - name: Cache pre-commit environment + uses: actions/cache@v4 + with: + path: | + ~/.cache/pre-commit + ~/.cache/pip + key: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: | + ${{ runner.os }}-pre-commit- + + - name: Install pre-commit + run: pip install -U pre-commit + - name: Update pre-commit hooks - uses: vrslev/pre-commit-autoupdate@v1.0.0 + run: pre-commit autoupdate --color=always - name: Create Pull Request uses: peter-evans/create-pull-request@v7 @@ -23,4 +41,4 @@ jobs: commit-message: "chore(deps): Update pre-commit hooks" body: Update pre-commit hooks labels: dependencies,development - delete-branch: True + delete-branch: true diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml new file mode 100644 index 00000000..7b88ce02 --- /dev/null +++ b/.github/workflows/semantic-release.yml @@ -0,0 +1,60 @@ +name: Semantic Release + +on: + workflow_run: + workflows: + - Lint + types: + - completed + +permissions: + actions: write + contents: write + issues: write + pull-requests: write + +jobs: + release: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "20" + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm test + + - name: Generate release notes and version + id: semantic_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + RELEASE_TAG=$(npx semantic-release | tee /dev/stderr | grep -oP '(?<=next release version is )[^ ]+') + echo "RELEASE_TAG=$RELEASE_TAG" >> $GITHUB_ENV + + - name: Create release metadata files + run: | + # Determine FRAPPE_BRANCH if not already set + FRAPPE_BRANCH=${{ vars.FRAPPE_BRANCH || 'version-15' }} + echo "FRAPPE_BRANCH=$FRAPPE_BRANCH" >> $GITHUB_ENV + + # Save metadata to files + echo "${RELEASE_TAG}" > release_tag.txt + echo "${FRAPPE_BRANCH}" > frappe_branch.txt + + - name: Upload release metadata + uses: actions/upload-artifact@v4 + with: + name: release-metadata + path: | + release_tag.txt + frappe_branch.txt diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 024ade1c..de505fa0 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,17 +2,21 @@ name: Mark stale issues and pull requests on: schedule: - # Every day at 12:00 pm + # Every day at 00:00 UTC - cron: 0 0 * * * jobs: stale: + if: ${{ github.repository == 'digikwal/frappe_docker' }} runs-on: ubuntu-latest + steps: - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: This issue has been automatically marked as stale. You have a week to explain why you believe this is an error. - stale-pr-message: This PR has been automatically marked as stale. You have a week to explain why you believe this is an error. + stale-issue-message: > + This issue has been automatically marked as stale. You have a week to explain why you believe this is an error. + stale-pr-message: > + This PR has been automatically marked as stale. You have a week to explain why you believe this is an error. stale-issue-label: no-issue-activity stale-pr-label: no-pr-activity