diff --git a/.github/workflows/build-docker-internal.yml b/.github/workflows/build-docker-internal.yml deleted file mode 100644 index 9de17689..00000000 --- a/.github/workflows/build-docker-internal.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Push docker images to internal registry - -on: - # push: - # branches: [main] - # paths: - # - ".github/workflows/docker.yml" - workflow_run: - workflows: ["Build Linux Artifacts"] - types: - - completed - -env: - VERSION: 0.10.5 -jobs: - build: - if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest - timeout-minutes: 120 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Get Version - run: | - echo VERSION=$(cat share/const.go |grep 'const VERSION' | awk '{print $4}' | sed "s/\"//g")-unstable >> $GITHUB_ENV - - - name: Check Version - run: echo $VERSION - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - registry: hub.iqka.com - username: ${{ secrets.DOCKER_INTERNAL_USER }} - password: ${{ secrets.DOCKER_INTERNAL_TOKEN }} - - - name: Build Production - timeout-minutes: 60 - uses: docker/build-push-action@v6 - env: - DOCKER_CONTENT_TRUST: 1 - with: - context: ./docker/production - platforms: linux/amd64 - build-args: | - VERSION=${{ env.VERSION }} - ARCH=amd64 - push: true - tags: hub.iqka.com/yaoapp/yao:${{ env.VERSION }}-amd64 - - - name: Build Production Arm64 - timeout-minutes: 60 - uses: docker/build-push-action@v6 - env: - DOCKER_CONTENT_TRUST: 1 - with: - context: ./docker/production - platforms: linux/arm64 - build-args: | - VERSION=${{ env.VERSION }} - ARCH=arm64 - push: true - tags: hub.iqka.com/yaoapp/yao:${{ env.VERSION }}-arm64 diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 0c252d8c..fadc6452 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -90,3 +90,29 @@ jobs: ARCH=arm64 push: true tags: yaoapp/yao:${{ env.VERSION }}-arm64 + + - name: Build Production Slim + uses: docker/build-push-action@v6 + env: + DOCKER_CONTENT_TRUST: 1 + with: + context: ./docker/production-slim + platforms: linux/amd64 + build-args: | + VERSION=${{ env.VERSION }} + ARCH=amd64 + push: true + tags: yaoapp/yao:${{ env.VERSION }}-amd64-slim + + - name: Build Production Slim Arm64 + uses: docker/build-push-action@v6 + env: + DOCKER_CONTENT_TRUST: 1 + with: + context: ./docker/production-slim + platforms: linux/arm64 + build-args: | + VERSION=${{ env.VERSION }} + ARCH=arm64 + push: true + tags: yaoapp/yao:${{ env.VERSION }}-arm64-slim diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index abba7b72..332a2ad4 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -114,8 +114,6 @@ jobs: - name: Make Artifacts MacOS run: | make artifacts-macos - mv dist/release/yao-$VERSION-dev-darwin-arm64 dist/release/yao-$VERSION-unstable-darwin-arm64 - mv dist/release/yao-$VERSION-dev-darwin-amd64 dist/release/yao-$VERSION-unstable-darwin-amd64 - name: Install Certificates env: @@ -150,21 +148,31 @@ jobs: - name: Sign Artifacts run: | codesign --deep --force --verbose --timestamp --sign "Developer ID Application: ${{ secrets.APPLE_SIGN }}" dist/release/yao-$VERSION-unstable-darwin-arm64 - codesign --deep --force --verbose --timestamp --options runtime --sign "Developer ID Application: ${{ secrets.APPLE_SIGN }}" dist/release/yao-$VERSION-unstable-darwin-amd64 + codesign --deep --force --verbose --timestamp --sign "Developer ID Application: ${{ secrets.APPLE_SIGN }}" dist/release/yao-$VERSION-unstable-darwin-amd64 + codesign --deep --force --verbose --timestamp --sign "Developer ID Application: ${{ secrets.APPLE_SIGN }}" dist/release/yao-$VERSION-unstable-darwin-arm64-prod + codesign --deep --force --verbose --timestamp --sign "Developer ID Application: ${{ secrets.APPLE_SIGN }}" dist/release/yao-$VERSION-unstable-darwin-amd64-prod - name: Verify Signature run: | codesign --verify --deep --strict --verbose=2 dist/release/yao-$VERSION-unstable-darwin-arm64 codesign --verify --deep --strict --verbose=2 dist/release/yao-$VERSION-unstable-darwin-amd64 + codesign --verify --deep --strict --verbose=2 dist/release/yao-$VERSION-unstable-darwin-arm64-prod + codesign --verify --deep --strict --verbose=2 dist/release/yao-$VERSION-unstable-darwin-amd64-prod - name: Send to Apple Notary Service run: | zip -r dist/release/yao-$VERSION-unstable-darwin-arm64.zip dist/release/yao-$VERSION-unstable-darwin-arm64 zip -r dist/release/yao-$VERSION-unstable-darwin-amd64.zip dist/release/yao-$VERSION-unstable-darwin-amd64 + zip -r dist/release/yao-$VERSION-unstable-darwin-arm64-prod.zip dist/release/yao-$VERSION-unstable-darwin-arm64-prod + zip -r dist/release/yao-$VERSION-unstable-darwin-amd64-prod.zip dist/release/yao-$VERSION-unstable-darwin-amd64-prod xcrun notarytool submit dist/release/yao-$VERSION-unstable-darwin-arm64.zip --apple-id "${{ secrets.APPLE_ID }}" --team-id "${{ secrets.APPLE_TEAME_ID }}" --password "${{ secrets.APPLE_APP_SPEC_PASS }}" --output-format json xcrun notarytool submit dist/release/yao-$VERSION-unstable-darwin-amd64.zip --apple-id "${{ secrets.APPLE_ID }}" --team-id "${{ secrets.APPLE_TEAME_ID }}" --password "${{ secrets.APPLE_APP_SPEC_PASS }}" --output-format json + xcrun notarytool submit dist/release/yao-$VERSION-unstable-darwin-arm64-prod.zip --apple-id "${{ secrets.APPLE_ID }}" --team-id "${{ secrets.APPLE_TEAME_ID }}" --password "${{ secrets.APPLE_APP_SPEC_PASS }}" --output-format json + xcrun notarytool submit dist/release/yao-$VERSION-unstable-darwin-amd64-prod.zip --apple-id "${{ secrets.APPLE_ID }}" --team-id "${{ secrets.APPLE_TEAME_ID }}" --password "${{ secrets.APPLE_APP_SPEC_PASS }}" --output-format json rm -f dist/release/yao-$VERSION-unstable-darwin-arm64.zip rm -f dist/release/yao-$VERSION-unstable-darwin-amd64.zip + rm -f dist/release/yao-$VERSION-unstable-darwin-arm64-prod.zip + rm -f dist/release/yao-$VERSION-unstable-darwin-amd64-prod.zip - name: Archive production artifacts uses: actions/upload-artifact@v4 diff --git a/Makefile b/Makefile index 461c273e..945cf097 100644 --- a/Makefile +++ b/Makefile @@ -467,16 +467,21 @@ artifacts-macos: clean @CUI_COMMIT=$$(cd ../cui-v1.0 && git log | head -n 1 | awk '{print substr($$2, 0, 12)}') && \ sed -ie "s/const PRCUI = \"DEV\"/const PRCUI = \"$$CUI_COMMIT-${NOW}\"/g" share/const.go -# Making artifacts +# Making artifacts - dev builds (full debug symbols) mkdir -p dist - CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -v -o dist/yao-${VERSION}-dev-darwin-amd64 - CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -v -o dist/yao-${VERSION}-dev-darwin-arm64 + CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -v -o dist/yao-${VERSION}-unstable-darwin-amd64 + CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -v -o dist/yao-${VERSION}-unstable-darwin-arm64 + +# Making artifacts - prod builds (stripped, no UPX on macOS) + sed -i.tmp 's/const BUILDOPTIONS = ""/const BUILDOPTIONS = "-s -w (production, stripped)"/g' share/const.go && rm -f share/const.go.tmp + CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -v -ldflags="-s -w" -o dist/yao-${VERSION}-unstable-darwin-amd64-prod + CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -v -ldflags="-s -w" -o dist/yao-${VERSION}-unstable-darwin-arm64-prod mkdir -p dist/release mv dist/yao-*-* dist/release/ chmod +x dist/release/yao-*-* ls -l dist/release/ - dist/release/yao-${VERSION}-dev-darwin-amd64 version + dist/release/yao-${VERSION}-unstable-darwin-amd64 version .PHONY: debug @@ -554,10 +559,10 @@ prepare: clean @CUI_COMMIT=$$(cd .tmp/cui/v1.0 && git log | head -n 1 | awk '{print substr($$2, 0, 12)}') && \ sed -ie "s/const PRCUI = \"DEV\"/const PRCUI = \"$$CUI_COMMIT-${NOW}\"/g" share/const.go -# make release (development build, ~158M) +# make release (development build only, ~158M) .PHONY: release release: prepare -# Making artifacts +# Making artifacts - dev build mkdir -p dist CGO_ENABLED=1 go build -v -o dist/release/yao chmod +x dist/release/yao @@ -574,7 +579,7 @@ release: prepare codesign --deep --force --verify --verbose --sign "${APPLE_SIGN}" dist/release/yao ; \ fi -# make prod (production build with -s -w, ~111M on macOS, ~45-55M on Linux with UPX) +# make prod (production build only, ~111M on macOS) .PHONY: prod prod: prepare # Set BUILDOPTIONS @@ -584,7 +589,7 @@ prod: prepare sed -i.tmp 's/const BUILDOPTIONS = ""/const BUILDOPTIONS = "-s -w (production, stripped)"/g' share/const.go && rm -f share/const.go.tmp; \ fi -# Making artifacts +# Making artifacts - prod build mkdir -p dist CGO_ENABLED=1 go build -v -ldflags="-s -w" -o dist/release/yao-prod chmod +x dist/release/yao-prod @@ -620,6 +625,59 @@ prod: prepare @echo "" @echo "Test with: dist/release/yao-prod version --all" +# make release-all (build both dev and prod in one go) +.PHONY: release-all +release-all: prepare +# Making artifacts - dev build (~158M) + @echo "Building dev binary..." + mkdir -p dist + CGO_ENABLED=1 go build -v -o dist/release/yao + chmod +x dist/release/yao + +# Making artifacts - prod build (~111M on macOS) + @echo "Building prod binary..." + @if [ "$$(uname)" = "Linux" ]; then \ + sed -i.tmp 's/const BUILDOPTIONS = ""/const BUILDOPTIONS = "-s -w +upx (production, compressed)"/g' share/const.go && rm -f share/const.go.tmp; \ + else \ + sed -i.tmp 's/const BUILDOPTIONS = ""/const BUILDOPTIONS = "-s -w (production, stripped)"/g' share/const.go && rm -f share/const.go.tmp; \ + fi + CGO_ENABLED=1 go build -v -ldflags="-s -w" -o dist/release/yao-prod + chmod +x dist/release/yao-prod + +# UPX compression (Linux only) + @if [ "$$(uname)" = "Linux" ]; then \ + echo "Compressing with UPX..."; \ + if command -v upx > /dev/null 2>&1; then \ + upx --best dist/release/yao-prod; \ + else \ + echo "WARNING: UPX not found. Install with: apt install upx"; \ + echo "Skipping compression."; \ + fi; \ + else \ + echo "Note: UPX compression skipped on macOS (not supported)"; \ + fi + +# Clean up and restore bindata.go and const.go + cp data/bindata.go.bak data/bindata.go + cp share/const.go.bak share/const.go + rm data/bindata.go.bak + rm share/const.go.bak + rm -rf .tmp + +# MacOS Application Signing + @if [ "$(OS)" = "Darwin" ]; then \ + codesign --deep --force --verify --verbose --sign "${APPLE_SIGN}" dist/release/yao ; \ + codesign --deep --force --verify --verbose --sign "${APPLE_SIGN}" dist/release/yao-prod ; \ + fi + + @echo "" + @echo "Done! Binaries:" + @ls -lh dist/release/yao dist/release/yao-prod + @echo "" + @echo "Test with:" + @echo " dist/release/yao version --all" + @echo " dist/release/yao-prod version --all" + .PHONY: linux-release linux-release: clean diff --git a/docker/production-slim/Dockerfile b/docker/production-slim/Dockerfile new file mode 100644 index 00000000..20a62b6d --- /dev/null +++ b/docker/production-slim/Dockerfile @@ -0,0 +1,31 @@ +# =========================================== +# Yao Production Slim (UPX compressed) +# docker build \ +# --build-arg VERSION="${VERSION}" \ +# --build-arg ARCH="${ARCH}" \ +# -t yaoapp/yao:${VERSION}-${ARCH}-slim . +# +# Build: +# docker build --platform linux/amd64 --build-arg VERSION=1.0.0 --build-arg ARCH=amd64 -t yaoapp/yao:1.0.0-amd64-slim . +# docker build --platform linux/arm64 --build-arg VERSION=1.0.0 --build-arg ARCH=arm64 -t yaoapp/yao:1.0.0-arm64-slim . +# +# Tests: +# docker run --rm yaoapp/yao:1.0.0-amd64-slim yao version +# docker run -d -p 5099:5099 yaoapp/yao:1.0.0-amd64-slim +# +# =========================================== +FROM alpine:latest +ARG VERSION +ARG ARCH +RUN apk --no-cache add curl +RUN curl -fsSL "https://pub-80136338e60643edbb55c6ca8a689cf8.r2.dev/archives/yao-${VERSION}-linux-${ARCH}-prod-upx" > /usr/local/bin/yao && \ + chmod +x /usr/local/bin/yao && \ + addgroup -S yao && adduser -S -G yao yao && \ + mkdir -p /data/app && \ + chown -R yao:yao /data/app + +USER yao +VOLUME /data/app +WORKDIR /data/app +EXPOSE 5099 +CMD ["/usr/local/bin/yao", "start"] diff --git a/docker/production/Dockerfile b/docker/production/Dockerfile index 68985492..d3b48cad 100644 --- a/docker/production/Dockerfile +++ b/docker/production/Dockerfile @@ -18,7 +18,7 @@ FROM alpine:latest ARG VERSION ARG ARCH RUN apk --no-cache add curl -RUN curl -fsSL "https://pub-80136338e60643edbb55c6ca8a689cf8.r2.dev/archives/yao-${VERSION}-linux-${ARCH}" > /usr/local/bin/yao && \ +RUN curl -fsSL "https://pub-80136338e60643edbb55c6ca8a689cf8.r2.dev/archives/yao-${VERSION}-linux-${ARCH}-prod" > /usr/local/bin/yao && \ chmod +x /usr/local/bin/yao && \ addgroup -S yao && adduser -S -G yao yao && \ mkdir -p /data/app && \