Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/build-image-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Build a test image from a PR code

on:
issue_comment:
types: [created]

jobs:
build-images:
if: >-
github.event.issue.pull_request &&
contains(github.event.comment.body, '/create-test-image') &&
contains(fromJSON('["OWNER", "COLLABORATOR"]'), github.event.comment.author_association)

runs-on: ubuntu-latest

permissions:
contents: read
pull-requests: write
packages: write

steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f

- name: Get Pull Request Information
id: pr
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});

core.setOutput('sha', pr.data.head.sha);
core.setOutput('ref', pr.data.head.ref);

- name: Checkout PR commit
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
ref: ${{ steps.pr.outputs.sha }}

- name: Set lowercase image owner
id: vars
run: |
echo "owner=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_OUTPUT

- name: Log in to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build & Push Docker image
run: |
SHA=$(echo "${{ steps.pr.outputs.sha }}" | cut -c1-7)
VERSION=pr-${{ github.event.issue.number }}-$SHA
OWNER=${{ steps.vars.outputs.owner }}

echo "Building image version: $VERSION"

docker buildx build \
--platform linux/amd64,linux/arm64 \
--file Dockerfile \
--target final \
--build-arg APP_VERSION=$VERSION \
--tag ghcr.io/$OWNER/leafwiki:$VERSION \
--annotation "index:org.opencontainers.image.title=LeafWiki" \
--annotation "index:org.opencontainers.image.description=LeafWiki – A fast wiki for people who think in folders, not feeds" \
--sbom=true \
--provenance=mode=max \
--push .
99 changes: 99 additions & 0 deletions .github/workflows/cleanup-pr-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Cleanup PR test images

on:
pull_request_target:
types: [closed]

schedule:
- cron: "0 3 1 * *"

permissions:
packages: write

jobs:
cleanup-closed-pr:
if: github.event_name == 'pull_request_target'
runs-on: ubuntu-latest

steps:
- name: Delete closed PR images
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
with:
script: |
const owner = context.repo.owner;
const packageName = context.repo.repo.toLowerCase();
const prefix = `pr-${context.payload.pull_request.number}-`;

const versions = await github.paginate(
github.rest.packages.getAllPackageVersionsForPackageOwnedByUser,
{
username: owner,
package_type: "container",
package_name: packageName,
per_page: 100,
}
);

for (const version of versions) {
const tags = version.metadata?.container?.tags ?? [];

if (!tags.some(tag => tag.startsWith(prefix))) {
continue;
}

core.info(`Deleting image: ${tags.join(", ")}`);

await github.rest.packages.deletePackageVersionForUser({
username: owner,
package_type: "container",
package_name: packageName,
package_version_id: version.id,
});
}


cleanup-old-images:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest

steps:
- name: Delete old PR images
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
with:
script: |
const owner = context.repo.owner;
const packageName = context.repo.repo.toLowerCase();
const retentionDays = 30;

const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - retentionDays);

const versions = await github.paginate(
github.rest.packages.getAllPackageVersionsForPackageOwnedByUser,
{
username: owner,
package_type: "container",
package_name: packageName,
per_page: 100,
}
);

for (const version of versions) {
const tags = version.metadata?.container?.tags ?? [];

const isPrImage = tags.some(tag => tag.startsWith("pr-"));
const createdAt = new Date(version.created_at);

if (!isPrImage || createdAt > cutoff) {
continue;
}

core.info(`Deleting old image: ${tags.join(", ")}`);

await github.rest.packages.deletePackageVersionForUser({
username: owner,
package_type: "container",
package_name: packageName,
package_version_id: version.id,
});
}
Loading