Skip to content

deploy-release

deploy-release #1329

name: deploy-release
on:
workflow_run:
workflows: ["build-release", "build-appimage", "build-flatpak", "build-appx", "build-snap", "build-wasm"]
types:
- completed
jobs:
check-tag:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
outputs:
matched_tag: ${{ steps.get_tag.outputs.matched_tag }}
steps:
- name: Find Tag from Commit SHA
id: get_tag
run: |
COMMIT_SHA="${{ github.event.workflow_run.head_sha }}"
echo "Looking for tags pointing to commit: $COMMIT_SHA"
TAG=$(gh api repos/${{ github.repository }}/git/matching-refs/tags \
| jq -r ".[] | select(.object.sha == \"$COMMIT_SHA\") | .ref" \
| grep '^refs/tags/v' || true)
if [ -z "$TAG" ]; then
echo "No matching v-tag found for commit."
echo "matched_tag=" >> "$GITHUB_OUTPUT"
else
echo "Found tag: $TAG"
echo "matched_tag=$TAG" >> "$GITHUB_OUTPUT"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
check-builds:
needs: check-tag
if: ${{ needs.check-tag.outputs.matched_tag != '' }}
runs-on: ubuntu-latest
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`,
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-tag, check-builds]
if: ${{ needs.check-tag.outputs.matched_tag != '' && needs.check-builds.outputs.all_builds_successful == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Determine Release Version
id: determine_version
run: |
TAG="${{ needs.check-tag.outputs.matched_tag }}"
VERSION_NUMBER="${TAG#refs/tags/v}" # Removes 'refs/tags/v' prefix
echo "Extracted version: $VERSION_NUMBER"
echo "VERSION_NUMBER=$VERSION_NUMBER" >> "$GITHUB_OUTPUT"
- 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 for artifacts 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',
});
// Organize extracted artifacts into subdirectories by workflow name and artifact name
const outputDir = `${artifactsPath}/${workflowName}/${artifact.name}`;
fs.mkdirSync(outputDir, { recursive: true });
const zip = new AdmZip(Buffer.from(download.data));
zip.extractAllTo(outputDir, true);
downloadedArtifactPaths.push(outputDir); // Collect the directories 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
}
}
// Flatten the list of directories into actual file paths for softprops/action-gh-release
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: Create Tagged Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.check-tag.outputs.matched_tag }}
name: MMapper ${{ steps.determine_version.outputs.VERSION_NUMBER }}
prerelease: false
draft: false
make_latest: true
generate_release_notes: true
overwrite: true
files: ${{ steps.download_artifacts.outputs.release_files }}
token: ${{ secrets.GITHUB_TOKEN }}