Skip to content

Commit 34fe687

Browse files
authored
Add link integrity check to markdown CI (#2041)
1 parent 253dfb6 commit 34fe687

31 files changed

Lines changed: 99 additions & 40 deletions

.github/workflows/markdown.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,63 @@ jobs:
7979
body: body
8080
});
8181
}
82+
83+
link-integrity:
84+
name: Link Integrity
85+
runs-on: ubuntu-latest
86+
87+
steps:
88+
- name: Checkout code
89+
uses: actions/checkout@v6
90+
91+
- name: Check internal markdown links resolve
92+
run: |
93+
rm -f /tmp/broken_links
94+
95+
# Escape %, newline, CR for GitHub Actions workflow commands
96+
escape_annotation() {
97+
local s="$1"
98+
s="${s//'%'/'%25'}"
99+
s="${s//$'\n'/'%0A'}"
100+
s="${s//$'\r'/'%0D'}"
101+
printf '%s' "$s"
102+
}
103+
104+
while IFS= read -r file; do
105+
dir=$(dirname "$file")
106+
107+
# Extract markdown links [text](path.md) or [text](path.md#anchor)
108+
grep -oE '\[[^]]*\]\([^)]+\.md(#[^)]*)?\)' "$file" 2>/dev/null \
109+
| grep -oE '\([^)]+\.md' \
110+
| sed 's/^(//' \
111+
| sed 's/#.*//' \
112+
| while IFS= read -r link; do
113+
114+
# Skip URLs
115+
case "$link" in http://*|https://*) continue ;; esac
116+
117+
# Resolve relative path
118+
resolved=$(cd "$dir" && realpath -q "$link" 2>/dev/null || echo "")
119+
if [ -z "$resolved" ] || [ ! -f "$resolved" ]; then
120+
safe_file="$(escape_annotation "$file")"
121+
safe_link="$(escape_annotation "$link")"
122+
echo "::warning file=${safe_file}::Broken link: ${safe_link} (target not found)"
123+
echo "$file -> $link" >> /tmp/broken_links
124+
fi
125+
done
126+
done < <(find . -name '*.md' \
127+
-not -path './node_modules/*' \
128+
-not -path './.git/*' \
129+
-not -path './.taskmaster/*' \
130+
-not -path './.claude/*')
131+
132+
if [ -f /tmp/broken_links ]; then
133+
count=$(wc -l < /tmp/broken_links)
134+
echo ""
135+
echo "Found $count broken link(s):"
136+
cat /tmp/broken_links
137+
echo ""
138+
echo "These are warnings for now. Fix broken links to keep docs navigable."
139+
else
140+
echo "All internal markdown links resolve."
141+
fi

docs/adr/0003-database-schema-migrations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ Edit the generated file with custom SQL, then Atlas manages it like any other mi
471471
* [Atlas GORM Integration](https://atlasgo.io/guides/orms/gorm)
472472
* [CockroachDB with Atlas](https://atlasgo.io/guides/databases/cockroachdb)
473473
* [GitHub Issue #3: Platform Services](https://github.com/meridianhub/meridian/issues/3)
474-
* [ADR-0004: Separated Schema Management](./0004-separated-schema-management.md)
474+
* [ADR-0004: Event Schema Evolution](./0004-event-schema-evolution.md)
475475
* [ADR-0005: Adapter Pattern for Layer Translation](./0005-adapter-pattern-layer-translation.md)
476476

477477
## Notes

docs/adr/0004-event-schema-evolution.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@ fields handle 90% of evolution needs. New event types handle the remaining 10% (
381381
## Links
382382

383383
- [ADR-0005: Adapter Pattern for Layer Translation](./0005-adapter-pattern-layer-translation.md)
384-
- [ADR-0006: Schema Management with Adapters](./0006-schema-management-adapters.md)
385384
- [Protocol Buffers Language Guide](https://protobuf.dev/programming-guides/proto3/)
386385
- [buf CLI Documentation](https://buf.build/docs/)
387386
- [BIAN Service Landscape 14.0.0](https://bian.org/servicelandscape-14-0-0/)

docs/adr/0005-adapter-pattern-layer-translation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Date: 2025-10-25
2222

2323
Accepted
2424

25-
Implements the separated concerns architecture from [ADR-0004](0004-separated-schema-management.md).
25+
Implements the separated concerns architecture from [ADR-0004](0004-event-schema-evolution.md).
2626

2727
## Context
2828

docs/adr/0006-tilt-local-development.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ Both are valid choices; Tilt won on developer experience.
741741
* [Tiltfile API Reference](https://docs.tilt.dev/api.html)
742742
* [Why Tilt? (Blog)](https://blog.tilt.dev/2019/04/09/designing-a-better-interface-for-microservices-development.html)
743743
* [Tilt vs Skaffold Comparison](https://docs.tilt.dev/choosing_a_local_dev_solution.html)
744-
* [Local Kubernetes Guide](../tilt.md)
744+
* [Local Kubernetes Guide](../skills/tilt.md)
745745
* [ADR-0001: Record Architecture Decisions](./0001-record-architecture-decisions.md)
746746

747747
## Notes

docs/adr/0017-temporal-quality-ladder.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ The following Meridian concepts have no direct BIAN equivalent:
11931193
### Internal ADRs
11941194

11951195
* [ADR-0013: Universal Quantity Type System](0013-generic-asset-quantity-types.md) - Quantity and rate types
1196-
* [ADR-0014: Dynamic Asset Registry & Lifecycle](0014-dynamic-asset-registry.md) - Asset definitions and attributes
1196+
* [ADR-0014: Financial Instrument Reference Data](0014-financial-instrument-reference-data.md) - Asset definitions and attributes
11971197
* [ADR-0016: Tenant Isolation](0016-tenant-id-naming-strategy.md) - Multi-tenancy and schema separation
11981198
* [ADR-0018: Settlement & Reconciliation](0018-settlement-reconciliation.md) - Settlement snapshots, temporal authority, reconciliation workflows
11991199

docs/adr/0018-settlement-reconciliation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ The following Meridian concepts extend or have no direct BIAN equivalent:
10161016

10171017
* [ADR-0004: Event-Driven Architecture](0004-event-schema-evolution.md) - Event contracts and publishing patterns
10181018
* [ADR-0013: Universal Quantity Type System](0013-generic-asset-quantity-types.md) - Quantity and rate types
1019-
* [ADR-0014: Dynamic Asset Registry & Lifecycle](0014-dynamic-asset-registry.md) - Asset definitions and attributes
1019+
* [ADR-0014: Financial Instrument Reference Data](0014-financial-instrument-reference-data.md) - Asset definitions and attributes
10201020
* [ADR-0016: Tenant Isolation](0016-tenant-id-naming-strategy.md) - Multi-tenancy and schema separation
10211021
* [ADR-0017: Temporal Quality Ledger](0017-temporal-quality-ladder.md) - Measurement log, quality ladder, supersession, corrections
10221022

docs/adr/0025-clearing-purpose-specialization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Create separate tables: `deposit_clearing_accounts`, `withdrawal_clearing_accoun
166166

167167
## Links
168168

169-
* [ADR-0024: Internal Account Service](0024-internal-account-service.md)
169+
* [ADR-0024: Internal Bank Account Service](0024-internal-bank-account-service.md)
170170
* [Internal Account README](../../services/internal-account/README.md)
171171
* [Proto Definitions](../../api/proto/meridian/internal_account/v1/internal_account.proto)
172172
* [BIAN Internal Account Service Domain](https://bian.org/semantic-apis/internal-account/)

docs/adr/0031-getbalance-nil-guard-retention.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Retain the explicit nil check with a descriptive error.
8282
## Links
8383

8484
* [ADR-0023: Balance Delegation to Position Keeping](0023-balance-delegation-to-position-keeping.md)
85-
* [ADR-0024: Internal Account Service](0024-internal-account-service.md)
85+
* [ADR-0024: Internal Bank Account Service](0024-internal-bank-account-service.md)
8686
* Related code: `services/internal-account/service/server.go` (GetBalance method)
8787

8888
## Notes

docs/adr/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Architectural Decision Records) format.
6767
| [ADR-0022](0022-instrument-successor-lineage.md) | Instrument Successor Lineage | Proposed | 2025-12-28 |
6868
<!-- markdownlint-disable-next-line MD013 -->
6969
| [ADR-0023](0023-balance-delegation-to-position-keeping.md) | Balance Delegation to Position Keeping | Accepted | 2026-01-08 |
70-
| [ADR-0024](0024-internal-account-service.md) | Internal Account Service Domain | Accepted | 2026-01-15 |
70+
| [ADR-0024](0024-internal-bank-account-service.md) | Internal Account Service Domain | Accepted | 2026-01-15 |
7171
<!-- markdownlint-disable-next-line MD013 -->
7272
| [ADR-0025](0025-clearing-purpose-specialization.md) | Clearing Purpose Specialization | Accepted | 2026-01-16 |
7373
<!-- markdownlint-disable-next-line MD013 -->
@@ -131,7 +131,7 @@ graph LR
131131
- [ADR-0017](0017-temporal-quality-ladder.md) - Temporal Quality Ledger (Data Physics)
132132
- [ADR-0018](0018-settlement-reconciliation.md) - Settlement & Reconciliation (Lifecycle)
133133
- [ADR-0023](0023-balance-delegation-to-position-keeping.md) - Balance Delegation to Position Keeping
134-
- [ADR-0024](0024-internal-account-service.md) - Internal Account Service Domain
134+
- [ADR-0024](0024-internal-bank-account-service.md) - Internal Account Service Domain
135135
- [ADR-0025](0025-clearing-purpose-specialization.md) - Clearing Purpose Specialization
136136
- [ADR-0026](0026-canonical-ingestion-contract.md) - Canonical Ingestion Contract
137137

0 commit comments

Comments
 (0)