mirror of
https://github.com/ThePhaseless/Byparr.git
synced 2026-09-24 14:20:08 +01:00
Add Building Feature (#276)
* feat: Build Docker images for PRs with branch name labels
- Remove condition preventing PR builds
- Add branch name extraction and sanitization
- Add branch labels to Docker images (org.opencontainers.image.branch and branch)
- Enable pushing of PR Docker images
- Sanitize branch names for Docker tags (replace / with -)
This allows PR images to be built and tagged with their branch names,
making it easier to test specific PR builds.
* feat: Add path filters to Docker workflow
Only build Docker images when relevant files change:
- Source code (src/**, main.py, tests/**)
- Docker configuration (Dockerfile, compose.yaml)
- Dependencies (pyproject.toml, uv.lock)
- Workflow file itself
This prevents unnecessary builds when only documentation or
other non-functional files are changed.
* feat: Add automatic cleanup of PR Docker images
Create a new workflow that automatically deletes Docker images
when a PR is closed or merged. This prevents accumulation of
old PR images in the container registry.
Features:
- Triggers on PR close/merge events
- Deletes images tagged with PR number and SHA
- Handles both architecture variants (amd64, arm64)
- Supports both organization and user repositories
- Provides detailed logging of cleanup operations
* refactor: Remove redundant branch label preparation
Remove duplicate branch name preparation step in merge-and-push job.
Branch labels are already added during the build step, so no need
to add them again when creating the manifest.
* refactor: Remove redundant label configurations
Remove custom label configurations from docker-publish workflow.
The docker/metadata-action already sets standard OCI labels by
default, so explicit label configuration is unnecessary.
Also removed unused BRANCH_TAG variable preparation.
* refactor: Use PR number for Docker image tags instead of SHA
Changed Docker image tagging strategy for pull requests:
- Use pr-{number}-{arch} for individual platform builds
- Use pr-{number} for final manifest
- Non-PR builds still use SHA-based tags
Benefits:
- Simpler, more readable tags for PRs
- Easier to identify which PR an image belongs to
- Cleanup script simplified to match only PR number tags
Updated cleanup workflow to match new tag pattern.
* docs: Add PR Docker image tags to README
Document the pr-{number} tag pattern used for pull request images.
These images are automatically built for PRs and cleaned up when
the PR is closed.
---------
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
co-authored by
Claude
parent
fd256a3ab6
commit
c45a464462
@@ -0,0 +1,107 @@
|
||||
name: Cleanup PR Docker Images
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Delete PR Docker images
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const owner = context.repo.owner.toLowerCase();
|
||||
const repo = context.repo.repo.toLowerCase();
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
|
||||
// Get the package
|
||||
const packageName = `${repo}`;
|
||||
|
||||
console.log(`Cleaning up images for PR #${prNumber}`);
|
||||
|
||||
// Check if owner is an org or user
|
||||
let isOrg = false;
|
||||
try {
|
||||
await github.rest.orgs.get({ org: owner });
|
||||
isOrg = true;
|
||||
console.log(`Repository owner is an organization`);
|
||||
} catch (error) {
|
||||
console.log(`Repository owner is a user account`);
|
||||
}
|
||||
|
||||
try {
|
||||
// Get all versions of the package
|
||||
let versions;
|
||||
if (isOrg) {
|
||||
versions = await github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg({
|
||||
package_type: 'container',
|
||||
package_name: packageName,
|
||||
org: owner,
|
||||
per_page: 100
|
||||
});
|
||||
} else {
|
||||
versions = await github.rest.packages.getAllPackageVersionsForPackageOwnedByUser({
|
||||
package_type: 'container',
|
||||
package_name: packageName,
|
||||
username: owner,
|
||||
per_page: 100
|
||||
});
|
||||
}
|
||||
|
||||
// Filter versions that match this PR (pr-123, pr-123-amd64, pr-123-arm64)
|
||||
const prVersions = versions.data.filter(version => {
|
||||
const tags = version.metadata?.container?.tags || [];
|
||||
// Match tags like: pr-123, pr-123-amd64, pr-123-arm64
|
||||
return tags.some(tag =>
|
||||
tag === `pr-${prNumber}` ||
|
||||
tag === `pr-${prNumber}-amd64` ||
|
||||
tag === `pr-${prNumber}-arm64`
|
||||
);
|
||||
});
|
||||
|
||||
console.log(`Found ${prVersions.length} image version(s) to delete`);
|
||||
|
||||
// Delete each version
|
||||
for (const version of prVersions) {
|
||||
console.log(`Deleting version ${version.id} with tags: ${version.metadata?.container?.tags?.join(', ')}`);
|
||||
try {
|
||||
if (isOrg) {
|
||||
await github.rest.packages.deletePackageVersionForOrg({
|
||||
package_type: 'container',
|
||||
package_name: packageName,
|
||||
org: owner,
|
||||
package_version_id: version.id
|
||||
});
|
||||
} else {
|
||||
await github.rest.packages.deletePackageVersionForUser({
|
||||
package_type: 'container',
|
||||
package_name: packageName,
|
||||
username: owner,
|
||||
package_version_id: version.id
|
||||
});
|
||||
}
|
||||
console.log(`✓ Deleted version ${version.id}`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to delete version ${version.id}:`, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Cleanup completed');
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
console.log('No package found - nothing to clean up');
|
||||
} else {
|
||||
console.error('Error during cleanup:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,26 @@ on:
|
||||
branches: ["*"]
|
||||
# Publish semver tags as releases.
|
||||
tags: ["v*.*.*"]
|
||||
paths:
|
||||
- "src/**"
|
||||
- "main.py"
|
||||
- "tests/**"
|
||||
- "Dockerfile"
|
||||
- "pyproject.toml"
|
||||
- "uv.lock"
|
||||
- "compose.yaml"
|
||||
- ".github/workflows/docker-publish.yml"
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- "src/**"
|
||||
- "main.py"
|
||||
- "tests/**"
|
||||
- "Dockerfile"
|
||||
- "pyproject.toml"
|
||||
- "uv.lock"
|
||||
- "compose.yaml"
|
||||
- ".github/workflows/docker-publish.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
@@ -54,7 +72,6 @@ jobs:
|
||||
|
||||
build:
|
||||
needs: test
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -74,8 +91,13 @@ jobs:
|
||||
run: |
|
||||
SURFIX=$(echo ${{ matrix.platform }} | cut -d'/' -f2)
|
||||
echo "SURFIX=$SURFIX" >> $GITHUB_OUTPUT
|
||||
# Generate a unique local tag for the image
|
||||
echo "LOCAL_TAG=${{ github.sha }}-$SURFIX" >> $GITHUB_OUTPUT
|
||||
|
||||
# Use PR number for PRs, SHA for everything else
|
||||
if [ "${{ github.event_name }}" == "pull_request" ]; then
|
||||
echo "LOCAL_TAG=pr-${{ github.event.pull_request.number }}-$SURFIX" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "LOCAL_TAG=${{ github.sha }}-$SURFIX" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
@@ -100,14 +122,14 @@ jobs:
|
||||
tags: type=raw,value=${{ steps.vars.outputs.LOCAL_TAG }}
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
# Build and export Docker image for each platform (without pushing)
|
||||
# Build and push Docker image for each platform
|
||||
- name: Build Docker image
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
pull: true
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
@@ -178,9 +200,16 @@ jobs:
|
||||
|
||||
echo $args
|
||||
|
||||
docker buildx imagetools create $args \
|
||||
${image}:${{github.sha}}-amd64 \
|
||||
${image}:${{github.sha}}-arm64
|
||||
# Use PR-based tags for PRs, SHA-based tags for everything else
|
||||
if [ "${{ github.event_name }}" == "pull_request" ]; then
|
||||
docker buildx imagetools create $args \
|
||||
${image}:pr-${{ github.event.pull_request.number }}-amd64 \
|
||||
${image}:pr-${{ github.event.pull_request.number }}-arm64
|
||||
else
|
||||
docker buildx imagetools create $args \
|
||||
${image}:${{github.sha}}-amd64 \
|
||||
${image}:${{github.sha}}-arm64
|
||||
fi
|
||||
|
||||
# Sign the manifest
|
||||
- name: Sign the manifests
|
||||
|
||||
Reference in New Issue
Block a user