name: Release Linux on: push: tags: - "v*" permissions: contents: write env: IMAGE_NAME: yaoapp/yao jobs: # =================================================================== # Build Linux Binaries (amd64 + arm64) # =================================================================== build: runs-on: ubuntu-latest container: image: yaoapp/yao-build:1.0.0 steps: - name: Build run: | export PATH=$PATH:/github/home/go/bin # Clone dependencies cd /app git clone https://github.com/yaoapp/kun.git /app/kun git clone https://github.com/yaoapp/xun.git /app/xun git clone https://github.com/yaoapp/gou.git /app/gou git clone https://github.com/yaoapp/v8go.git /app/v8go git clone https://github.com/yaoapp/cui.git /app/cui-v1.0 git clone https://github.com/yaoapp/yao-init.git /app/yao-init git clone https://github.com/yaoapp/yao.git /app/yao # Extract libv8 files=$(find /app/v8go -name "libv8*.zip") for file in $files; do dir=$(dirname "$file") echo "Extracting $file to directory $dir" unzip -o -d $dir $file rm -rf $dir/__MACOSX done # Set VERSION from git tag (required) cd /app/yao if [[ "$GITHUB_REF" != refs/tags/v* ]]; then echo "::error::This workflow requires a tag (refs/tags/v*). Got: $GITHUB_REF" exit 1 fi TAG_VERSION="${GITHUB_REF#refs/tags/v}" echo "Setting VERSION to $TAG_VERSION" sed -i "s/const VERSION = \".*\"/const VERSION = \"${TAG_VERSION}\"/g" share/const.go grep 'const VERSION' share/const.go make tools && make artifacts-linux mv /app/yao/dist/release/* /data/ ls -l /data - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: yao-linux path: /data/* # =================================================================== # Docker Images (multi-arch manifest: linux/amd64 + linux/arm64) # =================================================================== docker: needs: build runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 - name: Get Version id: version run: | if [[ "$GITHUB_REF" != refs/tags/v* ]]; then echo "::error::This workflow requires a tag (refs/tags/v*). Got: $GITHUB_REF" exit 1 fi VERSION="${GITHUB_REF#refs/tags/v}" echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "VERSION=${VERSION}" - name: Download Linux Artifacts uses: actions/download-artifact@v4 with: name: yao-linux path: artifacts - name: Prepare Docker Contexts run: | VERSION="${{ steps.version.outputs.version }}" ls -la artifacts/ # Development image uses dev (unstripped) binaries cp "artifacts/yao-${VERSION}-linux-amd64" docker/development/yao-amd64 cp "artifacts/yao-${VERSION}-linux-arm64" docker/development/yao-arm64 chmod +x docker/development/yao-* # Production image uses prod (stripped) binaries cp "artifacts/yao-${VERSION}-linux-amd64-prod" docker/production/yao-amd64 cp "artifacts/yao-${VERSION}-linux-arm64-prod" docker/production/yao-arm64 chmod +x docker/production/yao-* - 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: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build & Push Development (multi-arch) uses: docker/build-push-action@v6 with: context: ./docker/development platforms: linux/amd64,linux/arm64 push: true tags: | ${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}-dev ${{ env.IMAGE_NAME }}:dev - name: Build & Push Production (multi-arch) uses: docker/build-push-action@v6 with: context: ./docker/production platforms: linux/amd64,linux/arm64 push: true tags: | ${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} ${{ env.IMAGE_NAME }}:latest # =================================================================== # GitHub Release + R2 Upload (Linux binaries) # =================================================================== release: needs: build if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest steps: - name: Get Version id: version run: | if [[ "$GITHUB_REF" != refs/tags/v* ]]; then echo "::error::This workflow requires a tag. Got: $GITHUB_REF" exit 1 fi VERSION="${GITHUB_REF#refs/tags/v}" TAG="${GITHUB_REF#refs/tags/}" echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "tag=${TAG}" >> $GITHUB_OUTPUT - name: Download Linux Artifacts uses: actions/download-artifact@v4 with: name: yao-linux path: artifacts - name: Prepare Release Files run: | VERSION="${{ steps.version.outputs.version }}" mkdir -p release cp "artifacts/yao-${VERSION}-linux-amd64-prod" "release/yao-${VERSION}-linux-amd64" cp "artifacts/yao-${VERSION}-linux-arm64-prod" "release/yao-${VERSION}-linux-arm64" cp "artifacts/yao-${VERSION}-linux-amd64" "release/yao-${VERSION}-linux-amd64-dev" cp "artifacts/yao-${VERSION}-linux-arm64" "release/yao-${VERSION}-linux-arm64-dev" chmod +x release/yao-* for ARCH in amd64 arm64; do sha256sum "release/yao-${VERSION}-linux-${ARCH}" | awk '{print $1}' > "release/yao-linux-${ARCH}-prod.sha256" sha256sum "release/yao-${VERSION}-linux-${ARCH}-dev" | awk '{print $1}' > "release/yao-linux-${ARCH}-dev.sha256" done ls -lh release/ - name: Wait for Draft Release env: GH_TOKEN: ${{ github.token }} run: | TAG="${{ steps.version.outputs.tag }}" for i in $(seq 1 30); do if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" &>/dev/null; then echo "Draft release found for $TAG." exit 0 fi echo "Waiting for draft release... ($i/30)" sleep 10 done echo "::error::Timed out waiting for draft release $TAG" exit 1 - name: Upload Assets to GitHub Release env: GH_TOKEN: ${{ github.token }} run: | TAG="${{ steps.version.outputs.tag }}" gh release upload "$TAG" release/* --repo "$GITHUB_REPOSITORY" --clobber - name: Publish Release if Complete env: GH_TOKEN: ${{ github.token }} run: | TAG="${{ steps.version.outputs.tag }}" ASSET_COUNT=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets | length') echo "Current assets: $ASSET_COUNT / 16" if [ "$ASSET_COUNT" -ge 16 ]; then echo "All assets present, publishing release..." gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false --latest else echo "Assets incomplete ($ASSET_COUNT/16), waiting for other workflow to publish." fi - name: Upload Linux binaries to R2 env: AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} R2_ENDPOINTS: ${{ secrets.R2_ENDPOINTS }} R2_BUCKET: ${{ secrets.R2_BUCKET || 'releases' }} run: | aws configure set default.region us-east-1 aws configure set default.s3.signature_version s3v4 VERSION="${{ steps.version.outputs.version }}" PREFIX="yao/${VERSION}" for PLATFORM in linux-amd64 linux-arm64; do FILE="release/yao-${VERSION}-${PLATFORM}" NAME="yao-${VERSION}-${PLATFORM}" sha256sum "$FILE" | awk '{print $1}' > "/tmp/${NAME}.sha256" aws s3 cp "$FILE" "s3://${R2_BUCKET}/${PREFIX}/${NAME}" \ --endpoint-url "$R2_ENDPOINTS" \ --content-type "application/octet-stream" aws s3 cp "/tmp/${NAME}.sha256" "s3://${R2_BUCKET}/${PREFIX}/${NAME}.sha256" \ --endpoint-url "$R2_ENDPOINTS" \ --content-type "text/plain" echo "Uploaded: ${NAME} + ${NAME}.sha256" done