Skip to content

Feature/optimize image integrity: Adds automated orphaned image cleanup - #3659

Merged
jasonrandrews merged 8 commits into
ArmDeveloperEcosystem:mainfrom
sairamvarmabudharaju:feature/optimize-image-integrity
Aug 25, 2026
Merged

Feature/optimize image integrity: Adds automated orphaned image cleanup#3659
jasonrandrews merged 8 commits into
ArmDeveloperEcosystem:mainfrom
sairamvarmabudharaju:feature/optimize-image-integrity

Conversation

@sairamvarmabudharaju

Copy link
Copy Markdown
Contributor

Summary

This PR adds an orphaned-image audit and GitHub Actions workflow.

It:

  • Detects unreferenced images, broken paths, case mismatches, and malformed Markdown.
  • Checks both tracked source files and the rendered Hugo site.
  • Separates safe deletion candidates from images requiring review.
  • Creates a separate cleanup PR instead of deleting directly from main.

Safety

Cleanup uses a blob-verified audit manifest, rebuilds Hugo after proposed deletions, and verifies that no new reference problems were introduced. Ambiguous images remain untouched, and cleanup PRs are never auto-merged.

The workflow supports manual audits and runs automatically at 09:00 UTC on January 1, May 1, and September 1 in the official Arm repository only. We can change and adjust if we have to.

Validation

Repository checklist

Create a Learning Path review: Not applicable — this PR adds repository tooling.

  • I have checked my contribution for confidential information

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution under the terms of the Creative Commons Attribution 4.0 International License.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds repository automation to audit image reference integrity (missing paths, malformed Markdown, case mismatches) and to propose safe orphan-image deletions via a bot-owned cleanup PR, backed by a Hugo-rendered site scan and a blob-verified manifest.

Changes:

  • Adds a scheduled + manually-invokable GitHub Actions workflow to run the full rendered-site audit and (optionally) open/update a cleanup PR.
  • Introduces a new orphan_images.py auditor/cleanup tool plus a comprehensive unit test suite.
  • Updates the audit-images skill documentation and image guidance to include the new orphan/reference-integrity workflow.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.github/workflows/image-integrity.yml Adds the scheduled/manual workflow that runs the rendered audit and can propose a cleanup PR.
.github/skills/audit-images/scripts/orphan_images.py Implements the orphan/reference-integrity audit, safe reference fixes, manifest application, and cleanup verification.
.github/skills/audit-images/tests/test_orphan_images.py Adds unit tests covering reference detection, classification, manifest validation, and CLI flows.
.github/skills/audit-images/SKILL.md Documents how to run the new orphan/reference-integrity workflow alongside existing image audits.
.github/skills/audit-images/references/image-guidance.md Extends image cleanup guidance with orphan/reference-integrity best practices.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/skills/audit-images/scripts/orphan_images.py
Comment thread .github/skills/audit-images/scripts/orphan_images.py Outdated
Comment thread .github/workflows/image-integrity.yml
Comment thread .github/skills/audit-images/references/image-guidance.md Outdated

@annietllnd annietllnd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Sai! Thanks for putting this together. The overall workflow is useful, but I wonder whether we can simplify the script around the way it will actually be used.

Keeping both JSON and Markdown seems reasonable if JSON drives the automation and Markdown is only the human-readable report (is that the case?). I'd remove the plain text one as per my comment.

I would also consider removing the direct manual deletion mode. My understanding is that we will always generate the report first and then:

  • Handle cleanup manually outside the script for the ones that require review.
  • Have the workflow to create an automated deletion PR for the straight-forward cases.

I checked several supported syntax cases and found no current examples of:

  • reference-style images: ![alt][reference]
  • angle-bracket image destinations: ![alt](<image.png>)
  • data-src images

Unless these are formats we explicitly want to support, could we remove those branches for now? Can you please double check too and remove that functionality if you agree?

Also wanted to note that manual review will always be required because the script cannot understand every Learning Path’s context. For example, a LP in draft mode (search for draft: true in the repo to see what I mean) may have an intentionally incomplete image reference. I therefore wonder whether the detailed reasoning in the report is necessary. The image path, related source file and line, and a high-level category may be enough for someone to review the result. More advanced reasoning increases the script and report size but may still fail on future corner cases.

For this initial cleanup of approximately 100 images, I think it is important to review every candidate manually, including those classified as safe. After this one-off cleanup, I expect fewer than ten new candidates every six months, so manually reviewing each recurring report should be quick and a better way than trying to have the script reason about what went wrong.

My suggested ongoing workflow is:

  • Requires review → inspect and fix manually.
  • Safe-deletion candidate → create an automated deletion PR and review it before merging.

which I assume was your intention as well, just making sure :)

For the code that is left after this cleanup, it would also be helpful with very brief documentation for the code, regex-usecases are tricky to bat an eye at and understand what it does.

r"^\s*\[([^\]]+)\]:\s*(?:<([^>]+)>|(\S+))", re.MULTILINE
)
REFERENCE_IMAGE_RE = re.compile(r"!\[([^\]]*)\]\[([^\]]*)\]")
HTML_IMAGE_RE = re.compile(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have any HTML tags but stick with the markdown references. Could you check how many HTML we currently have and replace with markdown, please? And then remove the HTML approach. Ping me if you are unsure, happy to work through any corner cases

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally added HTML support because I considered editing existing published Learning Path Markdown outside this audits scope. I found three actual HTML image references, converted them to Markdown, and removed HTML support from the script. The other five occurrences are instructional examples, so I left them unchanged.

return errors


def analysis_text(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use this? CI seems to use the MD report which should be enough

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it. The CI now uses Markdown for the readable report and JSON for automation.

- Repair malformed, missing, and case-mismatched references before classifying files as orphaned
- Combine tracked source references with rendered Hugo output before deleting unique files
- Automatically delete only candidates classified as safe; review the smaller ambiguous group
- Use `orphan_images.py --fix-references` for deterministic bulk repairs; leave ambiguous matches for review

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not run both of these always? Maybe I'm missing something

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source and rendered Hugo checks now run together in every full audit. I kept --fix-references separate because it modifies Markdown, while the scheduled audit should remain read-only. Any deterministic repairs can be reviewed before rerunning the audit.

return (problem.kind, problem.path, problem.line, problem.target, problem.detail)


def needs_review_records(analysis: Analysis) -> list[dict[str, object]]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this level of reporting is needed, see main PR comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified this to include only the category, image path, and related Markdown file and line. The detailed reasoning and recommendations have been removed.

return f"[`{label}`]({url})"


def analysis_markdown(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing applies as with the needs_review_records, some of this reporting should be straight forward with only Category ("Unreferenced image candidates" and the image link itself). Had a look at the report you linked and all images in that suggestion list seem to be safe to delete (the PR doesn't remove the byte-copy, so this is still a safe deletion, right?) - the text doesn't seem to add any new information imo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified the report to a table containing category, image link, and related Markdown. Safe candidates are still only proposed through a separate cleanup PR and must be reviewed before merging.

@annietllnd
annietllnd self-requested a review August 25, 2026 17:24

@annietllnd annietllnd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the changes Sai! Looks good to me now.

@jasonrandrews
jasonrandrews merged commit 517ce67 into ArmDeveloperEcosystem:main Aug 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants