Skip to content

Fix xmldom iteration and circular dependency in adt-client#56

Merged
ThePlenkov merged 5 commits intomainfrom
claude/fix-ci-pipeline-V1KUE
Mar 2, 2026
Merged

Fix xmldom iteration and circular dependency in adt-client#56
ThePlenkov merged 5 commits intomainfrom
claude/fix-ci-pipeline-V1KUE

Conversation

@ThePlenkov
Copy link
Copy Markdown
Member

@ThePlenkov ThePlenkov commented Mar 2, 2026

Summary

This PR fixes compatibility issues with xmldom's DOM implementation and resolves a circular dependency between adt-client and adk packages. It also includes CI improvements and documentation for the Nx CI workflow.

Key Changes

xmldom Compatibility Fixes

  • DOM iteration: Replaced for...of loops with index-based iteration in packages/ts-xsd/src/xml/dom-utils.ts and packages/ts-xsd/src/xsd/parse.ts
    • xmldom's NamedNodeMap and NodeList are not iterable despite being array-like
    • Updated getAttributeValue(), getChildElements(), getAllChildElements(), getTextContent(), and extractXmlns() to use length-based loops
    • Added clarifying comments explaining the xmldom limitation

Circular Dependency Resolution

  • Removed @abapify/adk dependency from packages/adt-client/package.json
    • This was causing a circular dependency: adt-clientadkadt-client
    • The dependency was unused in the package

XML Parsing Improvements

  • Null-safety in packages/ts-xsd/src/xml/parse.ts:
    • Changed doc.documentElement to doc?.documentElement for safer access
    • Updated error message from "no root element" to "missing root element" for clarity

XSD Resolution Logic

  • Namespace handling in packages/ts-xsd/src/xsd/resolve.ts:
    • Updated condition to treat empty string as "no namespace" (!currentNs instead of currentNs === undefined)
    • Aligns with XSD parser behavior which sets "" when targetNamespace is absent

Nx Plugin Formatting

  • Code style in tools/nx-tsdown/src/plugin.ts:
    • Added .filter() to exclude root-level tsdown.config.ts files
    • Improved indentation consistency in the map function

CI & Documentation

  • GitHub Actions workflow (``.github/workflows/ci.yml`):

    • Added explicit ref checkout for pull requests to use PR head SHA instead of auto-created merge commit
    • Prevents 3-way merge from re-introducing removed dependencies
  • New Nx CI skill documentation (.claude/skills/nx-ci):

    • Comprehensive guide on replicating CI locally with nx affected
    • Instructions for checking formatting and running affected tasks
    • Troubleshooting circular dependency detection
    • Explains why nx affected is preferred over run-many

Implementation Details

  • All xmldom iteration changes maintain the same logic while using compatible APIs
  • The circular dependency fix is a clean removal with no functional impact
  • CI improvements ensure consistent behavior between local and GitHub Actions environments

https://claude.ai/code/session_019C2n4q24du7seSEKsRvyC4

Summary by CodeRabbit

  • Documentation

    • Added guidance for simulating CI locally with Nx, including affected project detection and circular dependency checks.
  • Bug Fixes

    • Improved XML/XSD parsing reliability with safer document access.
    • Fixed namespace resolution in XSD processing to handle empty namespace strings correctly.
  • Chores

    • Removed unused dependency.
    • Optimized build configuration to skip root-level configuration files.

Copilot AI and others added 5 commits March 2, 2026 19:55
… by merge commit)

The merge-from-main commit 12e09ef re-introduced `@abapify/adk: "*"` into
packages/adt-client/package.json. adt-client never actually imports from adk
(only has comments referencing it). Removing the dep permanently breaks the
circular dependency: adk→adt-client→adk.

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
…lar dep

actions/checkout@v6 for pull_request events (without explicit ref) checks out
GitHub's auto-created merge commit (refs/pull/N/merge). That merge commit is a
3-way merge: base has no @abapify/adk dep, main added it, PR branch didn't touch
it → git re-applies main's addition → circular dep returns in working directory.

Fix: use ref: github.event.pull_request.head.sha || github.sha
- PR events: checks out actual PR HEAD (correct package.json, no circular dep)
- Push events: github.event.pull_request.head.sha is empty → falls back to
  github.sha (pushed commit SHA) — same behaviour as before
- nrwl/nx-set-shas still computes the correct affected range from git history

Also document the 3-way merge pitfall in .claude/skills/nx-ci.

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
The root tsdown.config.ts is a shared config base, not a package entry point.
Filtering it out prevents nx-tsdown from creating a spurious build target on
the workspace root project which has no src/ directory or package.json exports.

https://claude.ai/code/session_019C2n4q24du7seSEKsRvyC4
@xmldom/xmldom's NamedNodeMap and NodeList do not implement Symbol.iterator,
so for...of loops over attributes/childNodes throw "is not iterable".
Replace with index-based loops throughout dom-utils.ts and parse.ts.

Also fix two additional bugs:
- xml/parse.ts: guard against null doc from DOMParser (empty string input)
  to throw "Invalid XML: missing root element" instead of a TypeError
- xsd/resolve.ts: treat empty string targetNamespace as "no namespace"
  so chameleon schema elements (e.g. abapGit from abapgit.xsd) are
  correctly merged into the resolved output

These bugs were surface-level hidden because the affected packages were
not "affected" in previous CI runs. Changing nx-tsdown/src/plugin.ts
(an NX plugin) marks all projects as affected, running all tests.

https://claude.ai/code/session_019C2n4q24du7seSEKsRvyC4
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Fix xmldom compatibility by replacing for...of loops with index-based iteration
• Remove circular dependency between adt-client and adk packages
• Fix CI checkout to use PR head SHA instead of auto-created merge commit
• Exclude workspace root tsdown.config.ts from nx-tsdown plugin
• Add comprehensive Nx CI skill documentation for local development
Diagram
flowchart LR
  A["xmldom Iteration Fix"] --> B["Index-based loops in dom-utils.ts"]
  C["Circular Dependency"] --> D["Remove @abapify/adk from adt-client"]
  E["CI Improvements"] --> F["Checkout PR head SHA"]
  E --> G["Exclude root tsdown.config.ts"]
  H["Documentation"] --> I["Add nx-ci skill guide"]
Loading

Grey Divider

File Changes

1. packages/ts-xsd/src/xml/dom-utils.ts 🐞 Bug fix +12/-8

Fix xmldom iteration in DOM utility functions

• Replaced for...of loops with index-based iteration for NamedNodeMap and NodeList
• Updated getAttributeValue(), getChildElements(), getAllChildElements(), and getTextContent()
 functions
• Added clarifying comments explaining xmldom's lack of iterable support

packages/ts-xsd/src/xml/dom-utils.ts


2. packages/ts-xsd/src/xml/parse.ts 🐞 Bug fix +2/-2

Add null-safety to XML document parsing

• Changed doc.documentElement to doc?.documentElement for safer null access
• Updated error message from "no root element" to "missing root element"

packages/ts-xsd/src/xml/parse.ts


3. packages/ts-xsd/src/xsd/parse.ts 🐞 Bug fix +3/-2

Fix xmldom iteration in namespace extraction

• Replaced for...of loop with index-based iteration in extractXmlns() function
• Added comment explaining xmldom NamedNodeMap iteration limitation

packages/ts-xsd/src/xsd/parse.ts


View more (5)
4. packages/ts-xsd/src/xsd/resolve.ts 🐞 Bug fix +2/-1

Align namespace handling with XSD parser

• Changed condition from currentNs === undefined to !currentNs
• Treats empty string as "no namespace" to align with XSD parser behavior
• Added clarifying comment about targetNamespace handling

packages/ts-xsd/src/xsd/resolve.ts


5. tools/nx-tsdown/src/plugin.ts 🐞 Bug fix +31/-29

Exclude root tsdown.config from plugin

• Added .filter() to exclude workspace root tsdown.config.ts files
• Improved indentation consistency in the map function
• Prevents spurious build target creation on workspace root

tools/nx-tsdown/src/plugin.ts


6. .claude/skills/nx-ci 📝 Documentation +71/-0

Add Nx CI skill documentation

• New comprehensive guide for replicating CI locally with nx affected
• Instructions for checking formatting and running affected tasks
• Troubleshooting section for circular dependency detection
• Explains 3-way merge pitfall and why nx affected is preferred

.claude/skills/nx-ci


7. .github/workflows/ci.yml 🐞 Bug fix +5/-0

Fix CI checkout to use PR head SHA

• Added explicit ref checkout using github.event.pull_request.head.sha
• Falls back to github.sha for push events
• Prevents 3-way merge from re-introducing removed dependencies
• Added detailed comments explaining the fix

.github/workflows/ci.yml


8. packages/adt-client/package.json 🐞 Bug fix +1/-2

Remove circular adk dependency

• Removed @abapify/adk dependency that was causing circular dependency
• Dependency was unused in the package
• Breaks circular chain: adk → adt-client → adk

packages/adt-client/package.json


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Mar 2, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Fork PR CI checkout 🐞 Bug ⛯ Reliability
Description
The CI workflow checks out github.event.pull_request.head.sha but does not set repository to the
PR head repo. For fork-based pull requests, that SHA is not present in the base repo, so the
checkout step can fail and CI won’t run for external contributors.
Code

.github/workflows/ci.yml[R21-25]

+          # For pull_request events, check out the PR head (not GitHub's auto-created
+          # merge commit). This prevents 3-way merge from re-introducing deps that
+          # the PR is supposed to remove. nrwl/nx-set-shas still computes the correct
+          # affected range from git history. Falls back to github.sha for push events.
+          ref: ${{ github.event.pull_request.head.sha || github.sha }}
Evidence
The workflow is triggered on pull_request events and the checkout step explicitly uses the PR head
SHA as the ref. However, actions/checkout defaults to the base repository unless repository is
set, which is incompatible with fork PR head SHAs.

.github/workflows/ci.yml[1-8]
.github/workflows/ci.yml[18-26]
Best Practice: actions/checkout (fork PR checkout guidance)

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
CI currently checks out `github.event.pull_request.head.sha`, but `actions/checkout` defaults to the base repo unless `repository` is provided. For fork PRs, the head SHA exists only in the fork repo, so checkout can fail and CI won&#x27;t run.

## Issue Context
Workflow triggers on `pull_request`, so fork PRs are a normal scenario for public repos. The current change explicitly prefers PR head SHA.

## Fix Focus Areas
- .github/workflows/ci.yml[18-26]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 2, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 513bcb9 and 6af06be.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • .claude/skills/nx-ci
  • .github/workflows/ci.yml
  • packages/adt-client/package.json
  • packages/ts-xsd/src/xml/dom-utils.ts
  • packages/ts-xsd/src/xml/parse.ts
  • packages/ts-xsd/src/xsd/parse.ts
  • packages/ts-xsd/src/xsd/resolve.ts
  • tools/nx-tsdown/src/plugin.ts

📝 Walkthrough

Walkthrough

This PR introduces documentation for Nx CI workflows, updates CI configuration to use PR-specific history, removes a dependency, and refactors DOM utilities and schema parsing to support xmldom's non-iterable collections while improving namespace resolution and filtering workspace-root configurations.

Changes

Cohort / File(s) Summary
Documentation & CI Setup
.claude/skills/nx-ci, .github/workflows/ci.yml
Introduces Nx CI skill documentation detailing local workflow simulation, commands, and pitfalls. Updates CI checkout step with ref parameter to use PR head SHA when available, preserving push-event behavior via fallback.
Dependencies
packages/adt-client/package.json
Removed "@abapify/adk" dependency; "@abapify/adt-schemas" remains unchanged.
XML & DOM Utilities
packages/ts-xsd/src/xml/dom-utils.ts, packages/ts-xsd/src/xml/parse.ts
Replaced for-of loops with index-based iteration over xmldom's non-iterable NodeList/NamedNodeMap. Added optional chaining for safer document element extraction and updated error message wording. Minor behavioral change: getTextContent now trims accumulated text.
XSD Parsing & Resolution
packages/ts-xsd/src/xsd/parse.ts, packages/ts-xsd/src/xsd/resolve.ts
Replaced for-of iteration with index-based loop in extractXmlns for compatibility. Updated namespace comparison logic to treat empty string as equivalent to undefined/no namespace, with clarifying comment.
Build Configuration
tools/nx-tsdown/src/plugin.ts
Added filter to exclude tsdown.config.ts files at workspace root (dirname !== '.') from build target mapping, preserving per-project configurations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 With whiskers twitching, I pen this verse,
Where xmldom loops no longer disperse,
Optional chains and namespaces align,
Nx workflows documented so fine!
Root configs filtered, dependencies slim—
The codebase leaps, and prospects look trim! 🌱

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-ci-pipeline-V1KUE

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 2, 2026

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented Mar 2, 2026

View your CI Pipeline Execution ↗ for commit 6af06be

Command Status Duration Result
nx affected -t lint test build e2e-ci --verbose... ✅ Succeeded 33s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-02 20:18:11 UTC

@ThePlenkov ThePlenkov merged commit 482d759 into main Mar 2, 2026
3 of 4 checks passed
@ThePlenkov ThePlenkov deleted the claude/fix-ci-pipeline-V1KUE branch March 2, 2026 20:18
Comment thread .github/workflows/ci.yml
Comment on lines +21 to +25
# For pull_request events, check out the PR head (not GitHub's auto-created
# merge commit). This prevents 3-way merge from re-introducing deps that
# the PR is supposed to remove. nrwl/nx-set-shas still computes the correct
# affected range from git history. Falls back to github.sha for push events.
ref: ${{ github.event.pull_request.head.sha || github.sha }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Fork pr ci checkout 🐞 Bug ⛯ Reliability

The CI workflow checks out github.event.pull_request.head.sha but does not set repository to the
PR head repo. For fork-based pull requests, that SHA is not present in the base repo, so the
checkout step can fail and CI won’t run for external contributors.
Agent Prompt
## Issue description
CI currently checks out `github.event.pull_request.head.sha`, but `actions/checkout` defaults to the base repo unless `repository` is provided. For fork PRs, the head SHA exists only in the fork repo, so checkout can fail and CI won't run.

## Issue Context
Workflow triggers on `pull_request`, so fork PRs are a normal scenario for public repos. The current change explicitly prefers PR head SHA.

## Fix Focus Areas
- .github/workflows/ci.yml[18-26]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

3 participants