diff --git a/.github/actions/build-and-upload-windows-package/action.yml b/.github/actions/build-and-upload-windows-package/action.yml new file mode 100644 index 00000000..e302fa9e --- /dev/null +++ b/.github/actions/build-and-upload-windows-package/action.yml @@ -0,0 +1,57 @@ +name: Build packages for windows and upload to artifact + +inputs: + package-file-name-prefix: + required: true + type: string + package-artifact-name-prefix: + required: true + type: string + backend-artifact-name-prefix: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Download windows-x64 backend file + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.backend-artifact-name-prefix }}-windows-x64 + path: ${{ runner.temp }}\backend + + - name: Download linux-amd64 packaged files + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.package-artifact-name-prefix }}-linux-amd64 + path: ${{ runner.temp }}\package + + - name: Extract frontend files from linux-amd64 package + shell: pwsh + run: | + New-Item -ItemType Directory -Path package + tar -xzf (Get-ChildItem ${{ runner.temp }}\package\${{ inputs.package-file-name-prefix }}-linux-amd64.tar.gz) -C package + + - name: Package windows-x64 package + shell: pwsh + run: | + New-Item -ItemType Directory -Path "ezbookkeeping" + New-Item -ItemType Directory -Path "ezbookkeeping\data" + New-Item -ItemType Directory -Path "ezbookkeeping\storage" + New-Item -ItemType Directory -Path "ezbookkeeping\log" + Copy-Item ${{ runner.temp }}\backend\ezbookkeeping.exe -Destination ezbookkeeping\ + Copy-Item -Recurse -Force package\public -Destination ezbookkeeping\public + Copy-Item -Recurse -Force conf -Destination ezbookkeeping\conf + Copy-Item -Recurse -Force templates -Destination ezbookkeeping\templates + Copy-Item .\LICENSE -Destination ezbookkeeping\ + Push-Location ezbookkeeping + 7z a -r -tzip -mx9 ..\${{ inputs.package-file-name-prefix }}-windows-x64.zip * + Pop-Location + Remove-Item -Recurse -Force ezbookkeeping + + - name: Upload windows artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.package-artifact-name-prefix }}-windows-x64 + path: ${{ inputs.package-file-name-prefix }}-windows-x64.zip + if-no-files-found: error diff --git a/.github/actions/build-linux-docker/action.yml b/.github/actions/build-linux-docker/action.yml new file mode 100644 index 00000000..4cedbb86 --- /dev/null +++ b/.github/actions/build-linux-docker/action.yml @@ -0,0 +1,98 @@ +name: Build docker image for linux + +inputs: + release-build: + required: false + type: string + check-3rd-api: + required: false + type: string + skip-tests: + required: false + type: string + platform: + required: true + type: string + platform-name: + required: true + type: string + docker-push: + required: true + type: boolean + docker-image-name: + required: true + type: string + docker-username: + required: false + type: string + docker-password: + required: false + type: string + docker-bake-meta-file-path: + required: true + type: string + docker-bake-meta-artifact-name: + required: true + type: string + docker-bake-digests-file-path: + required: true + type: string + docker-bake-digests-artifact-name-prefix: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Download docker bake meta artifact + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.docker-bake-meta-artifact-name }} + path: ${{ runner.temp }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + if: ${{ inputs.docker-username != '' && inputs.docker-password != '' }} + uses: docker/login-action@v3 + with: + username: ${{ inputs.docker-username }} + password: ${{ inputs.docker-password }} + + - name: Build docker for ${{ inputs.platform-name }} + id: bake + uses: docker/bake-action@v6 + with: + files: | + ./docker-bake.hcl + cwd://${{ inputs.docker-bake-meta-file-path }} + source: . + load: true + targets: image + set: | + *.tags=${{ inputs.docker-image-name }} + *.platform=${{ inputs.platform }} + *.args.RELEASE_BUILD=${{ inputs.release-build }} + *.args.BUILD_PIPELINE=1 + *.args.CHECK_3RD_API=${{ inputs.check-3rd-api }} + *.args.SKIP_TESTS=${{ inputs.skip-tests }} + *.output=type=image,push-by-digest=${{ inputs.docker-push }},name-canonical=true,push=${{ inputs.docker-push }} + *.output+=type=tar,dest=${{ runner.temp }}/docker-image.tar + + - name: Export digests file for ${{ inputs.platform-name }} + shell: bash + run: | + digest="${{ fromJSON(steps.bake.outputs.metadata).image['containerimage.digest'] }}" + mkdir -p ${{ inputs.docker-bake-digests-file-path }} + touch "${{ inputs.docker-bake-digests-file-path }}/${digest#sha256:}" + + - name: Upload ${{ inputs.platform-name }} digests artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.docker-bake-digests-artifact-name-prefix }}-${{ inputs.platform-name }} + path: ${{ inputs.docker-bake-digests-file-path }}/* + if-no-files-found: error diff --git a/.github/actions/build-windows-backend/action.yml b/.github/actions/build-windows-backend/action.yml new file mode 100644 index 00000000..4d23adc4 --- /dev/null +++ b/.github/actions/build-windows-backend/action.yml @@ -0,0 +1,68 @@ +name: Build backend file for windows + +inputs: + go-version: + required: false + default: "1.25.1" + mingw-version: + required: false + default: "14.2.0" + mingw-revison: + required: false + default: "v12-rev2" + release-build: + required: false + type: string + check-3rd-api: + required: false + type: string + skip-tests: + required: false + type: string + backend-artifact-name-prefix: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: ${{ inputs.go-version }} + + - name: Install MinGW + shell: pwsh + run: | + $mingwVersion = "${{ inputs.mingw-version }}" + $mingwRevision = "${{ inputs.mingw-revison }}" + $url = "https://github.com/niXman/mingw-builds-binaries/releases/download/${mingwVersion}-rt_${mingwRevision}/x86_64-${mingwVersion}-release-posix-seh-ucrt-rt_${mingwRevision}.7z" + $archive = "C:\mingw.7z" + $mingwDir = "C:\mingw64" + + Write-Host "Downloading MinGW from ${url}" + Invoke-WebRequest -Uri ${url} -OutFile ${archive} + + Remove-Item -Recurse -Force ${mingwDir} + New-Item -ItemType Directory -Path ${mingwDir} + + Write-Host "Extracting MinGW to ${mingwDir}" + 7z x ${archive} -oC:\ + "${mingwDir}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Build backend for windows-x64 + shell: pwsh + env: + RELEASE_BUILD: "${{ inputs.release-build }}" + BUILD_PIPELINE: "1" + CHECK_3RD_API: "${{ inputs.check-3rd-api }}" + SKIP_TESTS: "${{ inputs.skip-tests }}" + run: | + .\build.ps1 backend + + - name: Upload windows backend artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.backend-artifact-name-prefix }}-windows-x64 + path: ezbookkeeping.exe + if-no-files-found: error diff --git a/.github/actions/push-linux-docker/action.yml b/.github/actions/push-linux-docker/action.yml new file mode 100644 index 00000000..a7f346b4 --- /dev/null +++ b/.github/actions/push-linux-docker/action.yml @@ -0,0 +1,58 @@ +name: Push linux docker multi-arch image to registry + +inputs: + docker-image-name: + required: true + type: string + docker-username: + required: true + type: string + docker-password: + required: true + type: string + docker-bake-meta-file-path: + required: true + type: string + docker-bake-meta-artifact-name: + required: true + type: string + docker-bake-digests-file-path: + required: true + type: string + docker-bake-digests-artifact-name-prefix: + required: true + type: string + docker-image-tags: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Download docker bake meta artifact + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.docker-bake-meta-artifact-name }} + path: ${{ runner.temp }} + + - name: Download digests artifact + uses: actions/download-artifact@v4 + with: + pattern: ${{ inputs.docker-bake-digests-artifact-name-prefix }}-* + merge-multiple: true + path: ${{ inputs.docker-bake-digests-file-path }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ inputs.docker-username }} + password: ${{ inputs.docker-password }} + + - name: Create manifest and push + shell: bash + working-directory: ${{ inputs.docker-bake-digests-file-path }} + run: | + docker buildx imagetools create $(echo "${{ inputs.docker-image-tags }}" | xargs -I {} echo -n " -t {}") $(printf '${{ inputs.docker-image-name }}@sha256:%s ' *) diff --git a/.github/actions/upload-linux-package/action.yml b/.github/actions/upload-linux-package/action.yml new file mode 100644 index 00000000..d40eb34a --- /dev/null +++ b/.github/actions/upload-linux-package/action.yml @@ -0,0 +1,53 @@ +name: Upload linux package to artifact + +inputs: + platform: + required: true + type: string + platform-name: + required: true + type: string + docker-image-name: + required: true + type: string + docker-version: + required: true + type: string + docker-username: + required: true + type: string + docker-password: + required: true + type: string + package-file-name-prefix: + required: true + type: string + package-artifact-name-prefix: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Login to DockerHub + if: ${{ inputs.docker-username != '' && inputs.docker-password != '' }} + uses: docker/login-action@v3 + with: + username: ${{ inputs.docker-username }} + password: ${{ inputs.docker-password }} + + - name: Pull and save packaged files for ${{ inputs.platform-name }} + shell: bash + run: | + docker pull --platform ${{ inputs.platform }} ${{ inputs.docker-image-name }}:${{ inputs.docker-version }} + containerid=$(docker create "${{ inputs.docker-image-name }}:${{ inputs.docker-version }}") + docker cp ${containerid}:/ezbookkeeping ./ezbookkeeping + cd ezbookkeeping + tar -czf ../${{ inputs.package-file-name-prefix }}-${{ inputs.platform-name }}.tar.gz * + + - name: Upload artifact for ${{ inputs.platform-name }} + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.package-artifact-name-prefix }}-${{ inputs.platform-name }} + path: ${{ inputs.package-file-name-prefix }}-${{ inputs.platform-name }}.tar.gz + if-no-files-found: error diff --git a/.github/workflows/build-non-main-branch.yml b/.github/workflows/build-non-main-branch.yml index d2374e32..28631f47 100644 --- a/.github/workflows/build-non-main-branch.yml +++ b/.github/workflows/build-non-main-branch.yml @@ -6,27 +6,69 @@ on: - main jobs: + setup: + runs-on: ubuntu-latest + outputs: + docker-tags: ${{ steps.meta.outputs.tags }} + docker-labels: ${{ steps.meta.outputs.labels }} + ezbookkeeping-docker-bake-meta-file-path: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }} + ezbookkeeping-docker-bake-meta-artifact-name: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_artifact_name }} + ezbookkeeping-docker-digests-file-path: ${{ steps.variable.outputs.ezbookkeeping_docker_digests_file_path }} + ezbookkeeping-docker-digests-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_docker_digests_artifact_name_prefix }} + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ vars.DOCKER_IMAGE_NAME }} + tags: | + type=raw,value=dev-${{ github.run_id }} + + - name: Set up variables + id: variable + run: | + echo "ezbookkeeping_docker_bake_meta_file_path=${{ runner.temp }}/bake-meta.json" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_bake_meta_artifact_name=ezbookkeeping-build-dev-docker-bake-meta-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_digests_file_path=${{ runner.temp }}/digests" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_digests_artifact_name_prefix=ezbookkeeping-dev-digests-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + + - name: Rename docker bake meta file + run: | + mv "${{ steps.meta.outputs.bake-file }}" "${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }}" + + - name: Upload docker bake meta artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_artifact_name }} + path: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }} + if-no-files-found: error + build-linux-docker: runs-on: ubuntu-latest + needs: + - setup + strategy: + matrix: + include: + - platform: linux/amd64 + platform-name: linux-amd64 steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Login to DockerHub - uses: docker/login-action@v3 + - name: Checkout + uses: actions/checkout@v5 + + - uses: ./.github/actions/build-linux-docker with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Build - uses: docker/build-push-action@v6 - with: - file: Dockerfile - context: . - platforms: linux/amd64 - push: false - build-args: | - BUILD_PIPELINE=1 - CHECK_3RD_API=${{ vars.CHECK_3RD_API }} - SKIP_TESTS=${{ vars.SKIP_TESTS }} + check-3rd-api: ${{ vars.CHECK_3RD_API }} + skip-tests: ${{ vars.SKIP_TESTS }} + platform: ${{ matrix.platform }} + platform-name: ${{ matrix.platform-name }} + docker-push: false + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-bake-meta-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-file-path }} + docker-bake-meta-artifact-name: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-artifact-name }} + docker-bake-digests-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-file-path }} + docker-bake-digests-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-artifact-name-prefix }} diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 8b27c85d..9d89952a 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -6,214 +6,186 @@ on: - "v*.*.*" jobs: - build-linux-docker: + setup: runs-on: ubuntu-latest outputs: - image-tag: ${{ steps.meta.outputs.version }} + docker-version: ${{ steps.meta.outputs.version }} + docker-tags: ${{ steps.meta.outputs.tags }} + docker-labels: ${{ steps.meta.outputs.labels }} + ezbookkeeping-docker-bake-meta-file-path: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }} + ezbookkeeping-docker-bake-meta-artifact-name: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_artifact_name }} + ezbookkeeping-docker-digests-file-path: ${{ steps.variable.outputs.ezbookkeeping_docker_digests_file_path }} + ezbookkeeping-docker-digests-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_docker_digests_artifact_name_prefix }} + ezbookkeeping-package-file-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_package_file_name_prefix }} + ezbookkeeping-package-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_package_artifact_name_prefix }} + ezbookkeeping-backend-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_backend_artifact_name_prefix }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: | - ${{ secrets.DOCKER_USERNAME }}/ezbookkeeping + ${{ vars.DOCKER_IMAGE_NAME }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Set up variables + id: variable + run: | + echo "ezbookkeeping_docker_bake_meta_file_path=${{ runner.temp }}/bake-meta.json" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_bake_meta_artifact_name=ezbookkeeping-build-release-docker-bake-meta-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_digests_file_path=${{ runner.temp }}/digests" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_digests_artifact_name_prefix=ezbookkeeping-release-digests-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_package_file_name_prefix=ezbookkeeping-${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_package_artifact_name_prefix=ezbookkeeping-build-release-package-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_backend_artifact_name_prefix=ezbookkeeping-build-release-backend-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + + - name: Rename docker bake meta file + run: | + mv "${{ steps.meta.outputs.bake-file }}" "${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }}" + + - name: Upload docker bake meta artifact + uses: actions/upload-artifact@v4 with: - image: tonistiigi/binfmt:qemu-v8.1.5 + name: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_artifact_name }} + path: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }} + if-no-files-found: error - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + build-linux-docker: + runs-on: ubuntu-latest + needs: + - setup + strategy: + matrix: + include: + - platform: linux/amd64 + platform-name: linux-amd64 + - platform: linux/arm64/v8 + platform-name: linux-arm64 + - platform: linux/arm/v7 + platform-name: linux-armv7 + - platform: linux/arm/v6 + platform-name: linux-armv6 + steps: + - name: Checkout + uses: actions/checkout@v5 - - name: Login to DockerHub - uses: docker/login-action@v3 + - uses: ./.github/actions/build-linux-docker with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + release-build: 1 + check-3rd-api: ${{ vars.CHECK_3RD_API }} + skip-tests: ${{ vars.SKIP_TESTS }} + platform: ${{ matrix.platform }} + platform-name: ${{ matrix.platform-name }} + docker-push: true + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-username: ${{ vars.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-bake-meta-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-file-path }} + docker-bake-meta-artifact-name: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-artifact-name }} + docker-bake-digests-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-file-path }} + docker-bake-digests-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-artifact-name-prefix }} - - name: Build and push - uses: docker/build-push-action@v6 + push-linux-docker: + needs: + - setup + - build-linux-docker + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + - uses: ./.github/actions/push-linux-docker with: - file: Dockerfile - context: . - platforms: | - linux/amd64 - linux/arm64/v8 - linux/arm/v7 - linux/arm/v6 - push: true - build-args: | - RELEASE_BUILD=1 - BUILD_PIPELINE=1 - CHECK_3RD_API=${{ vars.CHECK_3RD_API }} - SKIP_TESTS=${{ vars.SKIP_TESTS }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-username: ${{ vars.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-bake-meta-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-file-path }} + docker-bake-meta-artifact-name: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-artifact-name }} + docker-bake-digests-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-file-path }} + docker-bake-digests-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-artifact-name-prefix }} + docker-image-tags: ${{ needs.setup.outputs.docker-tags }} - upload-linux-artifact: - needs: build-linux-docker + upload-linux-package: + needs: + - setup + - push-linux-docker runs-on: ubuntu-latest strategy: matrix: include: - - arch: linux/amd64 - arch_alias: linux-amd64 - - arch: linux/arm64/v8 - arch_alias: linux-arm64 - - arch: linux/arm/v7 - arch_alias: linux-armv7 - - arch: linux/arm/v6 - arch_alias: linux-armv6 + - platform: linux/amd64 + platform-name: linux-amd64 + - platform: linux/arm64/v8 + platform-name: linux-arm64 + - platform: linux/arm/v7 + platform-name: linux-armv7 + - platform: linux/arm/v6 + platform-name: linux-armv6 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - name: Login to DockerHub - uses: docker/login-action@v3 + - uses: ./.github/actions/upload-linux-package with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + platform: ${{ matrix.platform }} + platform-name: ${{ matrix.platform-name }} + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-version: ${{ needs.setup.outputs.docker-version }} + docker-username: ${{ vars.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + package-file-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-file-name-prefix }} + package-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-artifact-name-prefix }} - - name: Pull and save packaged files for ${{ matrix.arch }} - run: | - VERSION=${{ needs.build-linux-docker.outputs.image-tag }} - IMAGE=${{ secrets.DOCKER_USERNAME }}/ezbookkeeping:${VERSION} - docker pull --platform ${{ matrix.arch }} ${IMAGE} - cid=$(docker create "${IMAGE}") - docker cp ${cid}:/ezbookkeeping ./ezbookkeeping - docker rm ${cid} - cd ezbookkeeping - tar -czf ../ezbookkeeping-v${VERSION}-${{ matrix.arch_alias }}.tar.gz * - cd .. - rm -rf ezbookkeeping + build-windows-backend: + needs: + - setup + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v5 - - name: Upload artifact - uses: actions/upload-artifact@v4 + - uses: ./.github/actions/build-windows-backend with: - name: ezbookkeeping-${{ github.ref_name }}-${{ matrix.arch_alias }} - path: ezbookkeeping-${{ github.ref_name }}-${{ matrix.arch_alias }}.tar.gz - if-no-files-found: error + release-build: 1 + check-3rd-api: ${{ vars.CHECK_3RD_API }} + skip-tests: ${{ vars.SKIP_TESTS }} + backend-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-backend-artifact-name-prefix }} build-and-upload-windows-package: - needs: upload-linux-artifact + needs: + - setup + - build-windows-backend + - upload-linux-package runs-on: windows-latest - env: - GO_VERSION: "1.25.1" - MINGW_VERSION: "14.2.0" - MINGW_REVISION: "v12-rev2" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - name: Download linux-amd64 packaged files - uses: actions/download-artifact@v4 + - uses: ./.github/actions/build-and-upload-windows-package with: - name: ezbookkeeping-${{ github.ref_name }}-linux-amd64 - path: artifacts - - - name: Extract frontend files from linux-amd64 package - run: | - New-Item -ItemType Directory -Path package - tar -xzf (Get-ChildItem artifacts\ezbookkeeping-${{ github.ref_name }}-linux-amd64.tar.gz) -C package - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Install MinGW - run: | - $mingwVersion = "${{ env.MINGW_VERSION }}" - $mingwRevision = "${{ env.MINGW_REVISION }}" - $url = "https://github.com/niXman/mingw-builds-binaries/releases/download/${mingwVersion}-rt_${mingwRevision}/x86_64-${mingwVersion}-release-posix-seh-ucrt-rt_${mingwRevision}.7z" - $archive = "C:\mingw.7z" - $mingwDir = "C:\mingw64" - - Write-Host "Downloading MinGW from ${url}" - Invoke-WebRequest -Uri ${url} -OutFile ${archive} - - Remove-Item -Recurse -Force ${mingwDir} - New-Item -ItemType Directory -Path ${mingwDir} - - Write-Host "Extracting MinGW to ${mingwDir}" - 7z x ${archive} -oC:\ - "${mingwDir}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - name: Build backend for windows-x64 - env: - RELEASE_BUILD: "1" - BUILD_PIPELINE: "1" - CHECK_3RD_API: ${{ vars.CHECK_3RD_API }} - SKIP_TESTS: ${{ vars.SKIP_TESTS }} - run: | - .\build.ps1 backend - - - name: Package Windows build - run: | - New-Item -ItemType Directory -Path "ezbookkeeping" - New-Item -ItemType Directory -Path "ezbookkeeping\data" - New-Item -ItemType Directory -Path "ezbookkeeping\storage" - New-Item -ItemType Directory -Path "ezbookkeeping\log" - Copy-Item ezbookkeeping.exe -Destination ezbookkeeping\ - Copy-Item -Recurse -Force package\public -Destination ezbookkeeping\public - Copy-Item -Recurse -Force conf -Destination ezbookkeeping\conf - Copy-Item -Recurse -Force templates -Destination ezbookkeeping\templates - Copy-Item .\LICENSE -Destination ezbookkeeping\ - Push-Location ezbookkeeping - 7z a -r -tzip -mx9 ..\ezbookkeeping-${{ github.ref_name }}-windows-x64.zip * - Pop-Location - Remove-Item -Recurse -Force ezbookkeeping - - - name: Upload Windows artifact - uses: actions/upload-artifact@v4 - with: - name: ezbookkeeping-${{ github.ref_name }}-windows-x64 - path: ezbookkeeping-${{ github.ref_name }}-windows-x64.zip - if-no-files-found: error + package-file-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-file-name-prefix }} + package-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-artifact-name-prefix }} + backend-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-backend-artifact-name-prefix }} publish-release: runs-on: ubuntu-latest needs: - - upload-linux-artifact + - setup + - upload-linux-package - build-and-upload-windows-package steps: - - name: Download linux-amd64 packaged files + - name: Download all packaged files uses: actions/download-artifact@v4 with: - name: ezbookkeeping-${{ github.ref_name }}-linux-amd64 - path: ./release-files - - - name: Download linux-arm64 packaged files - uses: actions/download-artifact@v4 - with: - name: ezbookkeeping-${{ github.ref_name }}-linux-arm64 - path: ./release-files - - - name: Download linux-armv6 packaged files - uses: actions/download-artifact@v4 - with: - name: ezbookkeeping-${{ github.ref_name }}-linux-armv6 - path: ./release-files - - - name: Download linux-armv7 packaged files - uses: actions/download-artifact@v4 - with: - name: ezbookkeeping-${{ github.ref_name }}-linux-armv7 - path: ./release-files - - - name: Download windows-x64 packaged files - uses: actions/download-artifact@v4 - with: - name: ezbookkeeping-${{ github.ref_name }}-windows-x64 - path: ./release-files + pattern: ${{ needs.setup.outputs.ezbookkeeping_package_artifact_name_prefix }}-* + merge-multiple: true + path: release-files - name: Publish Release ${{ github.ref_name }} uses: softprops/action-gh-release@v2 diff --git a/.github/workflows/build-snapshot.yml b/.github/workflows/build-snapshot.yml index 6eb6658a..e62dc20e 100644 --- a/.github/workflows/build-snapshot.yml +++ b/.github/workflows/build-snapshot.yml @@ -6,173 +6,167 @@ on: - main jobs: - build-linux-docker: + setup: runs-on: ubuntu-latest outputs: - image-tag: ${{ steps.meta.outputs.version }} + docker-version: ${{ steps.meta.outputs.version }} + docker-tags: ${{ steps.meta.outputs.tags }} + docker-labels: ${{ steps.meta.outputs.labels }} + ezbookkeeping-docker-bake-meta-file-path: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }} + ezbookkeeping-docker-bake-meta-artifact-name: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_artifact_name }} + ezbookkeeping-docker-digests-file-path: ${{ steps.variable.outputs.ezbookkeeping_docker_digests_file_path }} + ezbookkeeping-docker-digests-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_docker_digests_artifact_name_prefix }} + ezbookkeeping-package-file-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_package_file_name_prefix }} + ezbookkeeping-package-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_package_artifact_name_prefix }} + ezbookkeeping-backend-artifact-name-prefix: ${{ steps.variable.outputs.ezbookkeeping_backend_artifact_name_prefix }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: | - ${{ secrets.DOCKER_USERNAME }}/ezbookkeeping + ${{ vars.DOCKER_IMAGE_NAME }} tags: | type=raw,value=SNAPSHOT-{{date 'YYYYMMDD'}}-${{ github.run_id }} type=raw,value=SNAPSHOT-{{date 'YYYYMMDD'}} type=raw,value=latest-snapshot - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Set up variables + id: variable + run: | + echo "ezbookkeeping_docker_bake_meta_file_path=${{ runner.temp }}/bake-meta.json" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_bake_meta_artifact_name=ezbookkeeping-build-dev-docker-bake-meta-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_digests_file_path=${{ runner.temp }}/digests" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_docker_digests_artifact_name_prefix=ezbookkeeping-dev-digests-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_package_file_name_prefix=ezbookkeeping-dev-package-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_package_artifact_name_prefix=ezbookkeeping-build-dev-package-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + echo "ezbookkeeping_backend_artifact_name_prefix=ezbookkeeping-build-dev-backend-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + + - name: Rename docker bake meta file + run: | + mv "${{ steps.meta.outputs.bake-file }}" "${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }}" + + - name: Upload docker bake meta artifact + uses: actions/upload-artifact@v4 with: - image: tonistiigi/binfmt:qemu-v8.1.5 + name: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_artifact_name }} + path: ${{ steps.variable.outputs.ezbookkeeping_docker_bake_meta_file_path }} + if-no-files-found: error - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + build-linux-docker: + runs-on: ubuntu-latest + needs: + - setup + strategy: + matrix: + include: + - platform: linux/amd64 + platform-name: linux-amd64 + - platform: linux/arm64/v8 + platform-name: linux-arm64 + - platform: linux/arm/v7 + platform-name: linux-armv7 + - platform: linux/arm/v6 + platform-name: linux-armv6 + steps: + - name: Checkout + uses: actions/checkout@v5 - - name: Login to DockerHub - uses: docker/login-action@v3 + - uses: ./.github/actions/build-linux-docker with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + check-3rd-api: ${{ vars.CHECK_3RD_API }} + skip-tests: ${{ vars.SKIP_TESTS }} + platform: ${{ matrix.platform }} + platform-name: ${{ matrix.platform-name }} + docker-push: true + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-username: ${{ vars.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-bake-meta-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-file-path }} + docker-bake-meta-artifact-name: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-artifact-name }} + docker-bake-digests-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-file-path }} + docker-bake-digests-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-artifact-name-prefix }} - - name: Build and push - uses: docker/build-push-action@v6 + push-linux-docker: + needs: + - setup + - build-linux-docker + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + - uses: ./.github/actions/push-linux-docker with: - file: Dockerfile - context: . - platforms: | - linux/amd64 - linux/arm64/v8 - linux/arm/v7 - linux/arm/v6 - push: true - build-args: | - BUILD_PIPELINE=1 - CHECK_3RD_API=${{ vars.CHECK_3RD_API }} - SKIP_TESTS=${{ vars.SKIP_TESTS }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-username: ${{ vars.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-bake-meta-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-file-path }} + docker-bake-meta-artifact-name: ${{ needs.setup.outputs.ezbookkeeping-docker-bake-meta-artifact-name }} + docker-bake-digests-file-path: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-file-path }} + docker-bake-digests-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-docker-digests-artifact-name-prefix }} + docker-image-tags: ${{ needs.setup.outputs.docker-tags }} - upload-linux-artifact: - needs: build-linux-docker + upload-linux-package: + needs: + - setup + - push-linux-docker runs-on: ubuntu-latest strategy: matrix: include: - - arch: linux/amd64 - arch_alias: linux-amd64 - - arch: linux/arm64/v8 - arch_alias: linux-arm64 - - arch: linux/arm/v7 - arch_alias: linux-armv7 - - arch: linux/arm/v6 - arch_alias: linux-armv6 + - platform: linux/amd64 + platform-name: linux-amd64 + - platform: linux/arm64/v8 + platform-name: linux-arm64 + - platform: linux/arm/v7 + platform-name: linux-armv7 + - platform: linux/arm/v6 + platform-name: linux-armv6 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - name: Login to DockerHub - uses: docker/login-action@v3 + - uses: ./.github/actions/upload-linux-package with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + platform: ${{ matrix.platform }} + platform-name: ${{ matrix.platform-name }} + docker-image-name: ${{ vars.DOCKER_IMAGE_NAME }} + docker-version: ${{ needs.setup.outputs.docker-version }} + docker-username: ${{ vars.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + package-file-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-file-name-prefix }} + package-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-artifact-name-prefix }} - - name: Pull and save packaged files for ${{ matrix.arch }} - run: | - TAG=${{ needs.build-linux-docker.outputs.image-tag }} - IMAGE=${{ secrets.DOCKER_USERNAME }}/ezbookkeeping:${TAG} - docker pull --platform ${{ matrix.arch }} ${IMAGE} - cid=$(docker create "${IMAGE}") - docker cp ${cid}:/ezbookkeeping ./ezbookkeeping - docker rm ${cid} - cd ezbookkeeping - tar -czf ../ezbookkeeping-dev-${{ github.run_id }}-${{ matrix.arch_alias }}.tar.gz * - cd .. - rm -rf ezbookkeeping + build-windows-backend: + needs: + - setup + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v5 - - name: Upload artifact - uses: actions/upload-artifact@v4 + - uses: ./.github/actions/build-windows-backend with: - name: ezbookkeeping-dev-${{ github.run_id }}-${{ matrix.arch_alias }} - path: ezbookkeeping-dev-${{ github.run_id }}-${{ matrix.arch_alias }}.tar.gz - if-no-files-found: error + check-3rd-api: ${{ vars.CHECK_3RD_API }} + skip-tests: ${{ vars.SKIP_TESTS }} + backend-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-backend-artifact-name-prefix }} build-and-upload-windows-package: - needs: upload-linux-artifact + needs: + - setup + - build-windows-backend + - upload-linux-package runs-on: windows-latest - env: - GO_VERSION: "1.25.1" - MINGW_VERSION: "14.2.0" - MINGW_REVISION: "v12-rev2" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - name: Download linux-amd64 packaged files - uses: actions/download-artifact@v4 + - uses: ./.github/actions/build-and-upload-windows-package with: - name: ezbookkeeping-dev-${{ github.run_id }}-linux-amd64 - path: artifacts - - - name: Extract frontend files from linux-amd64 package - run: | - New-Item -ItemType Directory -Path package - tar -xzf (Get-ChildItem artifacts\ezbookkeeping-dev-${{ github.run_id }}-linux-amd64.tar.gz) -C package - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Install MinGW - run: | - $mingwVersion = "${{ env.MINGW_VERSION }}" - $mingwRevision = "${{ env.MINGW_REVISION }}" - $url = "https://github.com/niXman/mingw-builds-binaries/releases/download/${mingwVersion}-rt_${mingwRevision}/x86_64-${mingwVersion}-release-posix-seh-ucrt-rt_${mingwRevision}.7z" - $archive = "C:\mingw.7z" - $mingwDir = "C:\mingw64" - - Write-Host "Downloading MinGW from ${url}" - Invoke-WebRequest -Uri ${url} -OutFile ${archive} - - Remove-Item -Recurse -Force ${mingwDir} - New-Item -ItemType Directory -Path ${mingwDir} - - Write-Host "Extracting MinGW to ${mingwDir}" - 7z x ${archive} -oC:\ - "${mingwDir}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - name: Build backend for windows-x64 - env: - BUILD_PIPELINE: "1" - CHECK_3RD_API: ${{ vars.CHECK_3RD_API }} - SKIP_TESTS: ${{ vars.SKIP_TESTS }} - run: | - .\build.ps1 backend - - - name: Package Windows build - run: | - New-Item -ItemType Directory -Path "ezbookkeeping" - New-Item -ItemType Directory -Path "ezbookkeeping\data" - New-Item -ItemType Directory -Path "ezbookkeeping\storage" - New-Item -ItemType Directory -Path "ezbookkeeping\log" - Copy-Item ezbookkeeping.exe -Destination ezbookkeeping\ - Copy-Item -Recurse -Force package\public -Destination ezbookkeeping\public - Copy-Item -Recurse -Force conf -Destination ezbookkeeping\conf - Copy-Item -Recurse -Force templates -Destination ezbookkeeping\templates - Copy-Item .\LICENSE -Destination ezbookkeeping\ - Push-Location ezbookkeeping - 7z a -r -tzip -mx9 ..\ezbookkeeping-dev-${{ github.run_id }}-windows-x64.zip * - Pop-Location - Remove-Item -Recurse -Force ezbookkeeping - - - name: Upload Windows artifact - uses: actions/upload-artifact@v4 - with: - name: ezbookkeeping-dev-${{ github.run_id }}-windows-x64 - path: ezbookkeeping-dev-${{ github.run_id }}-windows-x64.zip - if-no-files-found: error + package-file-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-file-name-prefix }} + package-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-package-artifact-name-prefix }} + backend-artifact-name-prefix: ${{ needs.setup.outputs.ezbookkeeping-backend-artifact-name-prefix }} diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 00000000..014fea58 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,34 @@ +variable "DEFAULT_TAG" { + default = "ezbookkeeping:local" +} + +// Special target: https://github.com/docker/metadata-action#bake-definition +target "docker-metadata-action" { + tags = ["${DEFAULT_TAG}"] +} + +// Default target if none specified +group "default" { + targets = ["image-local"] +} + +target "image" { + inherits = ["docker-metadata-action"] + context = "./" + dockerfile = "Dockerfile" +} + +target "image-local" { + inherits = ["image"] + output = ["type=docker"] +} + +target "image-all" { + inherits = ["image"] + platforms = [ + "linux/amd64", + "linux/arm64", + "linux/arm/v7", + "linux/arm/v6" + ] +}