diff --git a/.gitea/workflows/cloudflare-pages.yml b/.gitea/workflows/cloudflare-pages.yml new file mode 100644 index 0000000..a057fa2 --- /dev/null +++ b/.gitea/workflows/cloudflare-pages.yml @@ -0,0 +1,123 @@ +name: Deploy to Cloudflare Pages + +on: + push: + branches: + - main + workflow_dispatch: + +env: + OAUTH_DIR: oauth + KEEP_DEPLOYMENTS: 5 + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '21' + + - name: Install dependencies + run: | + cd ${{ env.OAUTH_DIR }} + npm install + + - name: Build OAuth app + run: | + cd ${{ env.OAUTH_DIR }} + NODE_ENV=production npm run build + - name: Copy OAuth build to static + run: | + rm -rf my-blog/static/assets + cp -rf ${{ env.OAUTH_DIR }}/dist/* my-blog/static/ + cp ${{ env.OAUTH_DIR }}/dist/index.html my-blog/templates/oauth-assets.html + + - name: Cache ailog binary + uses: actions/cache@v4 + with: + path: ./bin + key: ailog-bin-${{ runner.os }} + restore-keys: | + ailog-bin-${{ runner.os }} + + - name: Setup ailog binary + run: | + # Get expected version from Cargo.toml + EXPECTED_VERSION=$(grep '^version' Cargo.toml | cut -d'"' -f2) + echo "Expected version from Cargo.toml: $EXPECTED_VERSION" + + # Check current binary version if exists + if [ -f "./bin/ailog" ]; then + CURRENT_VERSION=$(./bin/ailog --version 2>/dev/null || echo "unknown") + echo "Current binary version: $CURRENT_VERSION" + else + CURRENT_VERSION="none" + echo "No binary found" + fi + + # Check OS + OS="${{ runner.os }}" + echo "Runner OS: $OS" + + # Use pre-packaged binary if version matches or extract from tar.gz + if [ "$CURRENT_VERSION" = "$EXPECTED_VERSION" ]; then + echo "Binary is up to date" + chmod +x ./bin/ailog + elif [ "$OS" = "Linux" ] && [ -f "./bin/ailog-linux-x86_64.tar.gz" ]; then + echo "Extracting ailog from pre-packaged tar.gz..." + cd bin + tar -xzf ailog-linux-x86_64.tar.gz + chmod +x ailog + cd .. + + # Verify extracted version + EXTRACTED_VERSION=$(./bin/ailog --version 2>/dev/null || echo "unknown") + echo "Extracted binary version: $EXTRACTED_VERSION" + + if [ "$EXTRACTED_VERSION" != "$EXPECTED_VERSION" ]; then + echo "Warning: Binary version mismatch. Expected $EXPECTED_VERSION but got $EXTRACTED_VERSION" + fi + else + echo "Error: No suitable binary found for OS: $OS" + exit 1 + fi + + - name: Build site with ailog + run: | + cd my-blog + ../bin/ailog build + + - name: List public directory + run: | + ls -la my-blog/public/ + + - name: Deploy to Cloudflare Pages + uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: ${{ secrets.CLOUDFLARE_PROJECT_NAME }} + directory: my-blog/public + wranglerVersion: '3' + + cleanup: + needs: deploy + runs-on: ubuntu-latest + if: success() + steps: + - name: Cleanup old deployments + run: | + curl -X PATCH \ + "https://api.cloudflare.com/client/v4/accounts/${{ secrets.CLOUDFLARE_ACCOUNT_ID }}/pages/projects/${{ secrets.CLOUDFLARE_PROJECT_NAME }}" \ + -H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d "{ \"deployment_configs\": { \"production\": { \"deployment_retention\": ${{ env.KEEP_DEPLOYMENTS }} } } }" \ No newline at end of file diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..30224a8 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,193 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Release tag (e.g., v1.0.0)' + required: true + default: 'v0.1.0' + +permissions: + contents: write + actions: read + +env: + CARGO_TERM_COLOR: always + OPENSSL_STATIC: true + OPENSSL_VENDOR: true + +jobs: + build: + name: Build ${{ matrix.target }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + matrix: + include: + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + artifact_name: ailog + asset_name: ailog-linux-x86_64 + - target: aarch64-unknown-linux-gnu + os: ubuntu-latest + artifact_name: ailog + asset_name: ailog-linux-aarch64 + - target: x86_64-apple-darwin + os: macos-latest + artifact_name: ailog + asset_name: ailog-macos-x86_64 + - target: aarch64-apple-darwin + os: macos-latest + artifact_name: ailog + asset_name: ailog-macos-aarch64 + + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - name: Install cross-compilation tools (Linux) + if: matrix.os == 'ubuntu-latest' && matrix.target == 'aarch64-unknown-linux-gnu' + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu + + - name: Configure cross-compilation (Linux ARM64) + if: matrix.target == 'aarch64-unknown-linux-gnu' + run: | + echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config.toml + echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config.toml + + - name: Cache cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache target directory + uses: actions/cache@v4 + with: + path: target + key: ${{ runner.os }}-${{ matrix.target }}-target-${{ hashFiles('**/Cargo.lock') }} + + - name: Build + run: cargo build --release --target ${{ matrix.target }} + + - name: Prepare binary + shell: bash + run: | + cd target/${{ matrix.target }}/release + + # Use appropriate strip command for cross-compilation + if [[ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]]; then + aarch64-linux-gnu-strip ${{ matrix.artifact_name }} || echo "Strip failed, continuing..." + elif [[ "${{ matrix.os }}" == "windows-latest" ]]; then + strip ${{ matrix.artifact_name }} || echo "Strip failed, continuing..." + else + strip ${{ matrix.artifact_name }} || echo "Strip failed, continuing..." + fi + + # Create archive + if [[ "${{ matrix.target }}" == *"windows"* ]]; then + 7z a ../../../${{ matrix.asset_name }}.zip ${{ matrix.artifact_name }} + else + tar czvf ../../../${{ matrix.asset_name }}.tar.gz ${{ matrix.artifact_name }} + fi + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.asset_name }} + path: ${{ matrix.asset_name }}.tar.gz + + release: + name: Create Release + needs: build + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Generate release notes + run: | + echo "## What's Changed" > release_notes.md + echo "" >> release_notes.md + echo "### Features" >> release_notes.md + echo "- AI-powered static blog generator" >> release_notes.md + echo "- AtProto OAuth integration" >> release_notes.md + echo "- Automatic translation support" >> release_notes.md + echo "- AI comment system" >> release_notes.md + echo "" >> release_notes.md + echo "### Platforms" >> release_notes.md + echo "- Linux (x86_64, aarch64)" >> release_notes.md + echo "- macOS (Intel, Apple Silicon)" >> release_notes.md + echo "" >> release_notes.md + echo "### Installation" >> release_notes.md + echo "\`\`\`bash" >> release_notes.md + echo "# Linux/macOS" >> release_notes.md + echo "tar -xzf ailog-linux-x86_64.tar.gz" >> release_notes.md + echo "chmod +x ailog" >> release_notes.md + echo "sudo mv ailog /usr/local/bin/" >> release_notes.md + echo "" >> release_notes.md + echo "\`\`\`" >> release_notes.md + + - name: Get tag name + id: tag_name + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT + else + echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + fi + + - name: Create Release with Gitea API + run: | + # Prepare release files + mkdir -p release + find artifacts -name "*.tar.gz" -exec cp {} release/ \; + + # Create release via Gitea API + RELEASE_RESPONSE=$(curl -X POST \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" \ + -H "Authorization: token ${{ github.token }}" \ + -H "Content-Type: application/json" \ + -d '{ + "tag_name": "${{ steps.tag_name.outputs.tag }}", + "name": "ailog ${{ steps.tag_name.outputs.tag }}", + "body": "'"$(cat release_notes.md | sed 's/"/\\"/g' | tr '\n' ' ')"'", + "draft": false, + "prerelease": '"$(if echo "${{ steps.tag_name.outputs.tag }}" | grep -E "(alpha|beta|rc)"; then echo "true"; else echo "false"; fi)"' + }') + + # Get release ID + RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id') + echo "Created release with ID: $RELEASE_ID" + + # Upload release assets + for file in release/*.tar.gz; do + if [ -f "$file" ]; then + filename=$(basename "$file") + echo "Uploading $filename..." + curl -X POST \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$filename" \ + -H "Authorization: token ${{ github.token }}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @"$file" + fi + done \ No newline at end of file