Skip to content

Merge pull request #4127 from dockerhub-toolshed/stress-ng-0.17.03 #5963

Merge pull request #4127 from dockerhub-toolshed/stress-ng-0.17.03

Merge pull request #4127 from dockerhub-toolshed/stress-ng-0.17.03 #5963

Workflow file for this run

name: Build image
on: [push, pull_request]
env:
MULLED_NAMESPACE: biocontainers
MULLED_TOOL_UTIL_SOURCE: git+https://github.com/bgruening/galaxy.git@mulled_quay_enhancements#subdirectory=packages/tool_util
jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- uses: astral-sh/setup-uv@v7
- run: docker --version
- run: docker info
- name: Build images
run: |
uv run --with "$MULLED_TOOL_UTIL_SOURCE" python -m galaxy.tool_util.deps.mulled.mulled_build_files --check-published --singularity --namespace $MULLED_NAMESPACE build-and-test ./combinations --verbose
- name: Save built images as artifacts (pull requests only)
if: github.event_name == 'pull_request' && github.event.pull_request.user.login != 'dockerhub-toolshed'
run: |
set -e
mkdir -p images
# Capture every image tagged into the build namespace (these are the ones
# freshly built by mulled; already-published images are skipped thanks to
# --check-published, so this is typically just the new/changed containers).
# mulled tags images as "quay.io/<namespace>/<image>:<tag>", so we grep
# the full repository name for the namespace segment.
docker images --format '{{.Repository}}:{{.Tag}}' \
| grep "/${MULLED_NAMESPACE}/" | sort -u > images/built-images.txt
echo "::notice::Found $(wc -l < images/built-images.txt) image(s) to export"
while IFS= read -r img; do
[ -z "$img" ] && continue
safe=$(echo "$img" | tr '/:' '__')
echo "Saving $img -> images/${safe}.tar"
docker save "$img" -o "images/${safe}.tar"
done < images/built-images.txt
# Include any Singularity images produced by the --singularity build
if [ -d singularity_import ] && [ "$(ls -A singularity_import 2>/dev/null)" ]; then
mkdir -p images/singularity
for f in singularity_import/*; do
[ -e "$f" ] || continue
safe=$(basename "$f" | tr ':/' '__')
cp "$f" "images/singularity/${safe}"
done
fi
- name: Upload container images (pull requests only)
if: github.event_name == 'pull_request' && github.event.pull_request.user.login != 'dockerhub-toolshed'
uses: actions/upload-artifact@v4
with:
name: container-images-pr-${{ github.event.pull_request.number }}
path: images/
retention-days: 7
if-no-files-found: warn
- name: Comment PR with container usage instructions
if: always() && github.event_name == 'pull_request' && github.event.pull_request.user.login != 'dockerhub-toolshed'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const prNumber = context.payload.pull_request.number;
const runId = context.runId;
const owner = context.repo.owner;
const repo = context.repo.repo;
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`;
const artifactName = `container-images-pr-${prNumber}`;
let built = [];
try {
built = fs.readFileSync('images/built-images.txt', 'utf8')
.split('\n').map(s => s.trim()).filter(Boolean);
} catch (e) {
// build failed before artifacts were saved
}
// Fetch the artifact ID so we can link directly to it.
let artifactUrl = runUrl;
try {
const { data: artifacts } = await github.rest.actions.listWorkflowRunArtifacts({
owner, repo, run_id: runId,
});
const art = artifacts.artifacts.find(a => a.name === artifactName);
if (art) {
artifactUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}/artifacts/${art.id}`;
}
} catch (e) {}
const marker = '<!-- container-artifacts-comment -->';
const buildOk = built.length > 0;
let body;
if (buildOk) {
const list = built.map(i => `- \`${i}\``).join('\n');
// Per-image load + run commands. The artifact is a single zip
// containing all built image tarballs, so download once.
const safeNames = built.map(img => img.replace(/[:/]/g, '_'));
const imageBlocks = built.map((img, i) => {
const safe = safeNames[i];
return [
'```bash',
`# Load and run ${img}`,
`unzip ${artifactName}.zip`,
`docker load -i ${safe}.tar`,
`docker run -i -t --rm ${img}`,
'```',
].join('\n');
}).join('\n\n');
body = [
'## 🐳 Container images built on this PR',
'',
'The following container image(s) were built successfully for testing:',
'',
list,
'',
'### How to use a container',
'',
`1. Download the \`${artifactName}\` artifact: [${artifactName}.zip](${artifactUrl})`,
` (or via CLI: \`gh run download ${runId} --repo ${owner}/${repo} -n ${artifactName}\`)`,
'2. Unzip and load the image, then run it:',
'',
imageBlocks,
'',
`> The artifact is retained for 7 days. Once the PR is merged to \`master\`, the images are pushed to quay.io/biocontainers.`,
'',
marker
].join('\n');
} else {
body = [
'## 🐳 Container images built on this PR',
'',
'No new container images were built for this PR (either the build failed, or all images were already published and skipped by `--check-published`).',
'',
`See the [workflow run](${runUrl}) for details.`,
'',
marker
].join('\n');
}
// Find an existing comment with our marker to update, else create a new one.
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const existing = comments.find(c => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});
}
- name: Upload images (if pushed to master branch)
if: github.ref == 'refs/heads/master' && github.repository_owner == 'BioContainers'
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
INVOLUCRO_AUTH: "https://${{ secrets.MY_USER }}:${{ secrets.MY_PASSWORD }}@quay.io/v1/?email=${{ secrets.MY_EMAIL }}"
run: |
mkdir -p ~/.ssh
ssh-keyscan -t rsa depot.galaxyproject.org >> ~/.ssh/known_hosts
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
ssh-add - <<< "${{ secrets.ORVAL_KEY }}"
uv run --with "$MULLED_TOOL_UTIL_SOURCE" python -m galaxy.tool_util.deps.mulled.mulled_build_files --check-published --namespace $MULLED_NAMESPACE --oauth-token ${{ secrets.QUAY_OAUTH_TOKEN }} push ./combinations
ls -l singularity_import
[ "$(ls -A singularity_import)" ] && echo 'uploading Singularity images' && scp singularity_import/*:* singularity@depot.galaxyproject.org:/srv/nginx/depot.galaxyproject.org/root/singularity/