diff --git a/.github/workflows/deploy-ipfs.yaml b/.github/workflows/deploy-ipfs.yaml index c61f8db..1597be4 100644 --- a/.github/workflows/deploy-ipfs.yaml +++ b/.github/workflows/deploy-ipfs.yaml @@ -1,41 +1,180 @@ name: Deploy to IPFS -permissions: - contents: read - pull-requests: write - statuses: write - on: push: - branches: - - main + branches: [main] workflow_dispatch: + inputs: + ref: + description: "Branch, tag, or SHA to deploy (default: current ref)" + required: false + default: "" jobs: - deploy: + build: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + fetch-depth: 1 + ref: ${{ github.event.inputs.ref || github.ref }} - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: - node-version: '20' - cache: 'yarn' + node-version: "20" + + - name: Install yarn for caching + run: | + # Install yarn globally via npm (required for setup-node caching) + # setup-node requires the package manager to be available before caching + if ! command -v yarn >/dev/null 2>&1; then + echo "Installing yarn via npm..." + npm install -g yarn + echo "✅ Yarn installed" + else + echo "✅ Yarn already available" + fi + yarn --version + + - name: Setup Node.js cache + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: "20" + cache: yarn - name: Install dependencies - run: yarn install + run: yarn install --frozen-lockfile - - name: Build project - run: yarn build + - name: Build env: - VITE_WEB_API_URL: ${{ vars.VITE_WEB_API_URL }} + VITE_WEB_API_URL: ${{ secrets.VITE_WEB_API_URL || vars.VITE_WEB_API_URL }} + run: yarn build - - name: Deploy to IPFS - uses: ipfs/ipfs-deploy-action@v1 - id: deploy + - name: Upload build artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: - path-to-deploy: dist - pinata-jwt-token: ${{ secrets.PINATA_JWT }} - github-token: ${{ github.token }} \ No newline at end of file + name: build-${{ github.sha }} + path: dist + if-no-files-found: error + + deploy: + needs: build + uses: gnosis/gh-action-pinata/.github/workflows/pinata-deployment.yml@main + with: + environment: prod + project_name: cfp-funding-tool + node_version: "20" + cache: yarn + build_dir: dist + use_prebuilt_build: true + build_artifact_name: build-${{ github.sha }} + secrets: + PINATA_JWT: ${{ secrets.PINATA_JWT }} + + post-deploy: + needs: deploy + runs-on: ubuntu-latest + timeout-minutes: 20 + if: always() + steps: + - name: Run primary health check (Pinata gateway) + run: | + echo "đŸĨ Running primary health check for production deployment (Pinata only)..." + + IPFS_HASH="${{ needs.deploy.outputs.ipfs_hash }}" + if [ -z "$IPFS_HASH" ] || [ "$IPFS_HASH" = "null" ]; then + echo "❌ Could not read ipfs_hash" + exit 1 + fi + + PINATA_URL="https://gateway.pinata.cloud/ipfs/$IPFS_HASH" + + # Wait briefly then try Pinata a few times + sleep 5 + for i in {1..3}; do + echo "Checking Pinata gateway (attempt $i): $PINATA_URL" + if curl -s --head --max-time 30 "$PINATA_URL" > /dev/null; then + echo "✅ Pinata gateway is accessible" + exit 0 + else + echo "âš ī¸ Pinata not accessible yet, retrying..." + sleep 15 + fi + done + + echo "❌ Pinata gateway not accessible after retries" + exit 1 + + - name: Test multi-gateway accessibility (informational) + continue-on-error: true + run: | + echo "🌐 Testing deployment accessibility across gateways..." + + IPFS_HASH="${{ needs.deploy.outputs.ipfs_hash }}" + + # Test multiple gateways + GATEWAYS=( + "https://gateway.pinata.cloud/ipfs/$IPFS_HASH" + "https://ipfs.io/ipfs/$IPFS_HASH" + "https://cloudflare-ipfs.com/ipfs/$IPFS_HASH" + "https://dweb.link/ipfs/$IPFS_HASH" + ) + + SUCCESSFUL=0 + TOTAL=${#GATEWAYS[@]} + + for gateway in "${GATEWAYS[@]}"; do + echo "Testing $gateway..." + if curl -s --head --max-time 30 "$gateway" > /dev/null; then + echo "✅ $gateway - accessible" + ((SUCCESSFUL++)) + else + echo "❌ $gateway - not accessible" + fi + done + + echo "📊 Accessibility: $SUCCESSFUL/$TOTAL gateways" + echo "â„šī¸ This is informational only; gateways other than Pinata may take minutes to propagate." + + - name: Create production deployment summary + run: | + IPFS_HASH="${{ needs.deploy.outputs.ipfs_hash }}" + PINATA_URL="${{ needs.deploy.outputs.pinata_url }}" + + { + echo '# 🚀 Production Deployment Complete' + echo '' + echo '## 📊 Deployment Details' + echo "- **Environment**: Production" + echo "- **Branch**: \`${{ github.ref_name }}\`" + echo "- **Commit**: \`${{ github.sha }}\`" + echo "- **Timestamp**: \`$(date -Iseconds)\`" + echo '' + echo '## 🌐 Primary Access URLs' + echo "- **Pinata Gateway**: [${PINATA_URL}](${PINATA_URL})" + echo "- **IPFS Gateway**: [https://ipfs.io/ipfs/${IPFS_HASH}](https://ipfs.io/ipfs/${IPFS_HASH})" + echo '' + echo '## 🔗 Alternative Gateways' + echo "- **Cloudflare IPFS**: [https://cloudflare-ipfs.com/ipfs/${IPFS_HASH}](https://cloudflare-ipfs.com/ipfs/${IPFS_HASH})" + echo "- **dweb.link**: [https://dweb.link/ipfs/${IPFS_HASH}](https://dweb.link/ipfs/${IPFS_HASH})" + echo '' + echo '## 📋 Technical Details' + echo "- **IPFS Hash**: \`${IPFS_HASH}\`" + } >> $GITHUB_STEP_SUMMARY + + - name: Deployment status + if: always() + run: | + if [ "${{ needs.deploy.result }}" = "success" ]; then + echo "✅ Production deployment completed successfully!" + echo "🌐 Site is now live on IPFS" + echo "📊 Check the Actions summary for all access URLs" + else + echo "❌ Production deployment failed" + echo "📋 Check the logs above for error details" + echo "🚨 Production site may be unavailable or outdated" + exit 1 + fi \ No newline at end of file diff --git a/package.json b/package.json index 7ff4090..5ce7e14 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "private": true, "version": "0.0.0", "type": "module", + "packageManager": "yarn@1.22.22", "scripts": { "dev": "vite", "build": "tsc -b && vite build",