deploy-beta #1146
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: deploy-beta | |
| on: | |
| workflow_run: | |
| workflows: ["build-release", "build-appimage", "build-flatpak", "build-appx", "build-snap", "build-wasm"] | |
| types: | |
| - completed | |
| jobs: | |
| check-builds: | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.workflow_run.head_branch == 'master' && github.event.workflow_run.conclusion == 'success' }} | |
| outputs: | |
| all_builds_successful: ${{ steps.check_builds.outputs.all_builds_successful }} | |
| successful_run_ids: ${{ steps.check_builds.outputs.successful_run_ids }} | |
| steps: | |
| - name: Check if all required builds are complete and get run IDs | |
| uses: actions/github-script@v8 | |
| id: check_builds | |
| with: | |
| script: | | |
| const requiredWorkflows = ['build-release', 'build-appimage', 'build-flatpak', 'build-appx', 'build-snap', 'build-wasm']; | |
| const commitSha = context.payload.workflow_run.head_sha; | |
| console.log(`Checking build status for commit: ${commitSha}`); | |
| let allSuccessful = true; | |
| const missingOrFailed = []; | |
| const successfulRunIds = {}; | |
| for (const workflowName of requiredWorkflows) { | |
| console.log(`Checking workflow: ${workflowName}`); | |
| // List workflow runs for the specific workflow file | |
| const { data: workflowRuns } = await github.rest.actions.listWorkflowRuns({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: `${workflowName}.yml`, | |
| branch: 'master', | |
| event: 'push', | |
| status: 'success' | |
| }); | |
| // Find the run that matches the head_sha of the triggering workflow_run event | |
| const matchingRun = workflowRuns.workflow_runs.find(run => run.head_sha === commitSha); | |
| if (!matchingRun) { | |
| allSuccessful = false; | |
| missingOrFailed.push(`${workflowName} (run for commit ${commitSha} not found or not successful)`); | |
| console.log(`Workflow ${workflowName} run for commit ${commitSha} not found or not successful.`); | |
| } else { | |
| successfulRunIds[workflowName] = matchingRun.id; | |
| console.log(`Workflow ${workflowName} run for commit ${commitSha} found with run ID: ${matchingRun.id}`); | |
| } | |
| } | |
| if (allSuccessful) { | |
| console.log('All required build workflows completed successfully. Run Ids:', successfulRunIds); | |
| core.setOutput('all_builds_successful', 'true'); | |
| core.setOutput('successful_run_ids', JSON.stringify(successfulRunIds)); | |
| } else { | |
| console.log(`Not all required build workflows completed successfully. Missing or failed: ${missingOrFailed.join(', ')}`); | |
| core.setOutput('all_builds_successful', 'false'); | |
| } | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| deploy: | |
| needs: check-builds | |
| if: ${{ needs.check-builds.outputs.all_builds_successful == 'true' }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Install adm-zip | |
| run: npm install adm-zip | |
| - name: Download all build artifacts | |
| uses: actions/github-script@v8 | |
| id: download_artifacts | |
| with: | |
| script: | | |
| const successfulRunIds = JSON.parse(process.env.SUCCESSFUL_RUN_IDS); | |
| const artifactsPath = `${process.env.GITHUB_WORKSPACE}/release_artifacts`; | |
| const fs = require('fs'); | |
| const AdmZip = require('adm-zip'); | |
| const downloadedArtifactPaths = []; | |
| // Ensure the base directory exists | |
| fs.mkdirSync(artifactsPath, { recursive: true }); | |
| for (const workflowName in successfulRunIds) { | |
| const runId = successfulRunIds[workflowName]; | |
| console.log(`Downloading artifacts for workflow '${workflowName}' (run_id: ${runId})`); | |
| try { | |
| const { data: artifactsList } = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id: runId, | |
| }); | |
| if (artifactsList.artifacts.length === 0) { | |
| console.log(`No artifacts found for run_id ${runId}`); | |
| continue; | |
| } | |
| for (const artifact of artifactsList.artifacts) { | |
| console.log(` Downloading artifact: ${artifact.name} (id: ${artifact.id})`); | |
| const download = await github.rest.actions.downloadArtifact({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| artifact_id: artifact.id, | |
| archive_format: 'zip', | |
| }); | |
| const outputDir = `${artifactsPath}/${workflowName}/${artifact.name}`; // Organize by workflow name and artifact name | |
| fs.mkdirSync(outputDir, { recursive: true }); | |
| const zip = new AdmZip(Buffer.from(download.data)); | |
| zip.extractAllTo(outputDir, true); | |
| downloadedArtifactPaths.push(outputDir); // Add the directory where artifacts were extracted | |
| console.log(` Extracted artifact to: ${outputDir}`); | |
| } | |
| } catch (error) { | |
| console.error(`Error downloading artifacts for run_id ${runId}:`, error); | |
| core.setFailed(`Failed to download artifacts for run_id ${runId}.`); | |
| return; // Stop the script if an error occurs | |
| } | |
| } | |
| // Prepare a comma-separated string of all extracted files/directories for the release action | |
| // This is more complex than just outputting the parent directories, as softprops/action-gh-release expects actual file paths. | |
| // You might need to flatten this list of directories into individual files if they are not in the top-level. | |
| // For now, let's collect the paths to the directories where artifacts were extracted. | |
| let filesToUpload = []; | |
| downloadedArtifactPaths.forEach(dirPath => { | |
| const files = fs.readdirSync(dirPath).map(file => `${dirPath}/${file}`); | |
| filesToUpload = filesToUpload.concat(files); | |
| }); | |
| core.setOutput('release_files', filesToUpload.join(',')); | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| env: | |
| SUCCESSFUL_RUN_IDS: ${{ needs.check-builds.outputs.successful_run_ids }} | |
| - name: List downloaded artifacts for verification | |
| run: | | |
| echo "Artifacts downloaded to ${{ github.workspace }}/release_artifacts:" | |
| ls -R ${{ github.workspace }}/release_artifacts | |
| echo "--- End of artifact listing ---" | |
| - name: Delete Previous Pre-release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| set -e | |
| RELEASE_TAG="beta" | |
| if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then | |
| echo "Beta release '$RELEASE_TAG' exists. Deleting the release..." | |
| gh release delete "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --yes || { echo "Failed to delete release: $RELEASE_TAG"; } # Add error handling | |
| gh api -X DELETE repos/$GITHUB_REPOSITORY/git/refs/tags/$RELEASE_TAG || true | |
| else | |
| echo "Beta release '$RELEASE_TAG' does not exist. No need to delete." | |
| fi | |
| - name: Update Beta Pre-release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: beta | |
| name: MMapper Beta | |
| prerelease: true | |
| draft: false | |
| generate_release_notes: true | |
| body: "Latest development build. Back up your map before using.\n\n" | |
| files: ${{ steps.download_artifacts.outputs.release_files }} | |
| token: ${{ secrets.GITHUB_TOKEN }} |