diff --git a/.github/workflows/deploy-playground-to-cdn.yml b/.github/workflows/deploy-playground-to-cdn.yml new file mode 100644 index 000000000..134bdb1b2 --- /dev/null +++ b/.github/workflows/deploy-playground-to-cdn.yml @@ -0,0 +1,177 @@ +name: Deploy Playground to CDN + +on: + workflow_dispatch: + inputs: + is_latest_release: + description: '当前分支是否是最新release版本' + required: true + default: true + type: boolean + +env: + HUAWEI_CLOUD_AK: ${{ secrets.HUAWEI_CLOUD_AK }} + HUAWEI_CLOUD_SK: ${{ secrets.HUAWEI_CLOUD_SK }} + HUAWEI_CLOUD_ENDPOINT: ${{ secrets.HUAWEI_CLOUD_ENDPOINT }} + HUAWEI_CLOUD_BUCKET: ${{ secrets.HUAWEI_CLOUD_BUCKET }} + +jobs: + check-secrets: + runs-on: ubuntu-latest + outputs: + secrets-ready: ${{ steps.check.outputs.secrets-ready }} + steps: + - name: Check required secrets + id: check + run: | + if [[ -z "${{ secrets.HUAWEI_CLOUD_AK }}" ]] || \ + [[ -z "${{ secrets.HUAWEI_CLOUD_SK }}" ]] || \ + [[ -z "${{ secrets.HUAWEI_CLOUD_ENDPOINT }}" ]] || \ + [[ -z "${{ secrets.HUAWEI_CLOUD_BUCKET }}" ]]; then + echo "secrets-ready=false" >> $GITHUB_OUTPUT + echo "::error::Required Huawei Cloud secrets are not configured." + echo "::error::Please set: HUAWEI_CLOUD_AK, HUAWEI_CLOUD_SK, HUAWEI_CLOUD_ENDPOINT, HUAWEI_CLOUD_BUCKET" + exit 1 + fi + echo "secrets-ready=true" >> $GITHUB_OUTPUT + echo "✅ All required secrets are configured" + + build: + # 指定运行环境为最新版本的ubuntu + runs-on: ubuntu-latest + outputs: + version-timestamp: ${{ steps.prepare-version.outputs.version_timestamp }} + cdn-base: ${{ steps.prepare-version.outputs.cdn_base }} + cdn-base-latest: ${{ steps.prepare-version.outputs.cdn_base_latest }} + obs-path: ${{ steps.prepare-version.outputs.obs_path }} + obs-path-latest: ${{ steps.prepare-version.outputs.obs_path_latest }} + steps: + # 步骤1: 检出代码 + - name: CheckOut Code + uses: actions/checkout@v4 + with: + ref: ${{ github.ref_name }} + + # 步骤2: 设置pnpm包管理器 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + # 步骤3: 设置Node.js环境 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 # 使用Node.js 20版本 + registry-url: 'https://registry.npmjs.org' # 设置npm registry地址 + + # 步骤4: 获取pnpm缓存目录路径 + - name: Get pnpm store directory + id: pnpm-cache + run: | + echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT + + # 步骤5: 配置pnpm缓存 + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + # 使用操作系统类型和pnpm-lock.yaml的哈希值作为缓存键 + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + # 步骤6: 安装项目依赖 + - name: Install dependencies + run: pnpm i --no-frozen-lockfile + + - id: prepare-version + name: Prepare version-timestamp + run: | + # Extract version from package.json + VERSION=$(node -p "require('./packages/playground/package.json').version") + + # Generate timestamp in YYYYMMDD-HHMMSS format + TIMESTAMP=$(TZ="Asia/Shanghai" date +%Y%m%d-%H%M%S) + + # Combine for version-timestamp + VERSION_TIMESTAMP="${VERSION}-${TIMESTAMP}" + + # Set CDN base path + CDN_BASE="https://res-static.opentiny.design/tiny-robot-playground/${VERSION_TIMESTAMP}/" + CDN_BASE_LATEST="https://res-static.opentiny.design/tiny-robot-playground/latest/" + OBS_PATH="tiny-robot-playground/${VERSION_TIMESTAMP}" + OBS_PATH_LATEST="tiny-robot-playground/latest" + + # Export as environment variables for subsequent steps + echo "VERSION_TIMESTAMP=$VERSION_TIMESTAMP" >> $GITHUB_ENV + echo "CDN_BASE=$CDN_BASE" >> $GITHUB_ENV + echo "OBS_PATH=$OBS_PATH" >> $GITHUB_ENV + + # Set outputs for job-level export + echo "version_timestamp=$VERSION_TIMESTAMP" >> $GITHUB_OUTPUT + echo "cdn_base=$CDN_BASE" >> $GITHUB_OUTPUT + echo "cdn_base_latest=$CDN_BASE_LATEST" >> $GITHUB_OUTPUT + echo "obs_path=$OBS_PATH" >> $GITHUB_OUTPUT + echo "obs_path_latest=$OBS_PATH_LATEST" >> $GITHUB_OUTPUT + + echo "Version-Timestamp: $VERSION_TIMESTAMP" + echo "CDN Base: $CDN_BASE" + echo "OBS Path: $OBS_PATH" + + # 构建Playground + - name: Build Playground + run: pnpm build:playground + env: + PLAYGROUND_BASE: ${{ env.CDN_BASE }} + + - name: Verify build output + run: ls -la ./packages/playground/dist + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: playground-dist + path: ./packages/playground/dist/ + retention-days: 1 + + deploy-cdn: + runs-on: ubuntu-latest + needs: [check-secrets, build] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: playground-dist + path: ./packages/playground/dist/ + + - name: Install obsutil + run: | + curl -o obsutil.tar.gz https://obs-community.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_linux_amd64.tar.gz + tar -xzf obsutil.tar.gz + chmod +x obsutil_linux_amd64_*/obsutil + sudo mv obsutil_linux_amd64_*/obsutil /usr/local/bin/obsutil + + - name: Configure and Upload to OBS + run: | + obsutil config -i=${{ env.HUAWEI_CLOUD_AK }} \ + -k=${{ env.HUAWEI_CLOUD_SK }} \ + -e=${{ env.HUAWEI_CLOUD_ENDPOINT }} + # Upload to versioned path + obsutil cp ./packages/playground/dist \ + obs://${{ env.HUAWEI_CLOUD_BUCKET }}/${{ needs.build.outputs.obs-path }} \ + -r -f -flat + + # If is_latest_release is true, also upload to latest path + if [ "${{ github.event.inputs.is_latest_release }}" = "true" ]; then + # use cdn-base-latest replace cdn-base in all ./packages/playground/dist files + find ./packages/playground/dist -type f \( -name "*.html" -o -name "*.js" -o -name "*.mjs" -o -name "*.css" \) \ + -exec sed -i "s|${{ needs.build.outputs.cdn-base }}|${{ needs.build.outputs.cdn-base-latest }}|g" {} + + obsutil cp ./packages/playground/dist \ + obs://${{ env.HUAWEI_CLOUD_BUCKET }}/${{ needs.build.outputs.obs-path-latest }} \ + -r -f -flat + fi + + echo "Uploaded to: obs://${{ env.HUAWEI_CLOUD_BUCKET }}/${{ needs.build.outputs.obs-path }}" + echo "CDN URL: https://res-static.opentiny.design/${{ needs.build.outputs.obs-path }}"