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
Empty file added .claude/agents/.gitkeep
Empty file.
Empty file added .claude/commands/.gitkeep
Empty file.
60 changes: 60 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"permissions": {
"allow": [
"Edit(/**)",
"Bash(yarn *)",
"Bash(npx *)",
"Bash(find *)",
"Bash(ls *)",
"Bash(cat *)",
"Bash(grep *)",
"Bash(node --version)",
"Bash(yarn --version)",
"Bash(tsc --version)",
"Bash(biome --version)",
"Bash(lefthook --version)",
"Bash(gh --version)",
"Bash(git *)",
"Bash(gh auth status)",
"Bash(gh repo view*)",
"Bash(gh pr*)",
"Bash(gh issue*)",
"Bash(gh api*)",
"WebFetch(domain:github.com)",
"WebFetch(domain:raw.githubusercontent.com)",
"WebFetch(domain:biomejs.dev)",
"WebFetch(domain:lefthook.dev)",
"mcp__atlassian__get*",
"mcp__atlassian__search*",
"mcp__atlassian__lookup*",
"mcp__atlassian__fetch",
"mcp__atlassian__atlassianUserInfo",
"mcp__context7__resolve-library-id",
"mcp__context7__query-docs"
],
"deny": [
"Bash(sudo *)",
"Read(**/.env)",
"Read(**/.env.*)",
"Edit(**/.env)",
"Edit(**/.env.*)",
"Bash(git reset*)",
"Bash(git push --force*)",
"Bash(git clean -f*)",
"Bash(git checkout -- *)",
"Bash(git checkout .)",
"Bash(git branch -D *)",
"Bash(git branch --delete --force *)",
"Bash(gh auth login)",
"Bash(gh auth logout)",
"Bash(gh repo create)",
"Bash(gh repo delete)",
"Bash(gh repo archive)",
"Bash(gh pr merge*)",
"Bash(gh release*)",
"Bash(gh secret*)",
"Bash(gh variable*)"
],
"ask": ["Bash(yarn dlx *)", "Bash(rm -rf *)"]
}
}
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

44 changes: 0 additions & 44 deletions .eslintrc.cjs

This file was deleted.

25 changes: 25 additions & 0 deletions .github/workflows/claude-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

permissions:
actions: write
contents: write
deployments: write
id-token: write
issues: write
pull-requests: write
statuses: write

jobs:
claude:
uses: reside-eng/workflow-templates/.github/workflows/claude-code.yml@v12
secrets: inherit
12 changes: 12 additions & 0 deletions .github/workflows/code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: PR code Review

on:
pull_request:
types: [opened, ready_for_review, reopened]
issue_comment:
types: [created]

jobs:
code-review:
uses: reside-eng/workflow-templates/.github/workflows/code-review.yml@v12
secrets: inherit
28 changes: 14 additions & 14 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ concurrency:
group: release-${{ github.ref }}

env:
NODE_VERSION: 20.x
NODE_VERSION: 24.x

jobs:
publish:
Expand All @@ -40,30 +40,30 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}

- name: Install dependencies
run: yarn install --frozen-lockfile
run: yarn install --immutable

- name: Verify formatting
run: yarn format:check
- name: Check
run: yarn check

- name: Lint
run: yarn lint
- name: Type check
run: yarn types:check

# - name: Test
# run: yarn test --coverage --silent
- name: Test
run: yarn test:cov

# - name: Upload coverage to Coveralls
# uses: coverallsapp/github-action@95b1a2355bd0e526ad2fd62da9fd386ad4c98474 # v2.2.1
# with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload coverage to Coveralls
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Build
run: yarn build

- name: Semantic Release
uses: cycjimmy/semantic-release-action@5982a02995853159735cb838992248c4f0f16166 # v2.7.0
uses: cycjimmy/semantic-release-action@b12c8f6015dc215fe37bc154d4ad456dd3833c90 # v6.0.0
id: semantic
with:
semantic_version: ^18
semantic_version: ^25
branches: |
[
'+([0-9])?(.{+([0-9]),x}).x',
Expand Down
24 changes: 12 additions & 12 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Verify
on: [pull_request]

env:
NODE_VERSION: 20.x
NODE_VERSION: 24.x

jobs:
build:
Expand All @@ -20,21 +20,21 @@ jobs:
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile
run: yarn install --immutable

- name: Verify formatting
run: yarn format:check
- name: Check
run: yarn check

- name: Lint
run: yarn lint
- name: Type check
run: yarn types:check

# - name: Test
# run: yarn test --coverage --silent
- name: Test
run: yarn test:cov

# - name: Upload coverage to Coveralls
# uses: coverallsapp/github-action@95b1a2355bd0e526ad2fd62da9fd386ad4c98474 # v2.2.1
# with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload coverage to Coveralls
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Build
run: yarn build
16 changes: 15 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,18 @@ node_modules
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
!.yarn/versions

# coverage + build artifacts
coverage
dist

# IDE
.vscode/*
!.vscode/extensions.json

# claude code worktrees (created on demand, not tracked)
.claude/worktrees/
.claude/memory
.claude/projects
.claude/settings.local.json
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.11.0
24.15.0
30 changes: 30 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# @side/replace-comment-html-action

GitHub Action that upserts HTML inside an issue/PR comment via CSS selectors. Two modes: `upsert` (replace existing or append) and `create-only` (never overwrite). When `parent-selector` is set, `selector` is treated as nested inside that parent and the parent comment body is updated in place. Consumed by other workflows as `uses: reside-eng/replace-comment-html-action@vN`.

## Stack

Yarn 4, Node 24 (engines `^24.0.0`), TypeScript 6 (`@tsconfig/node24`), ESM (`"type": "module"`). **Biome** (lint + format), **Lefthook** (hooks), **Vitest** (tests + coverage), **esbuild** (bundle to `dist/index.mjs`), **commitlint** (Conventional Commits).

`src/`:
- `index.ts` — entry; reads action inputs and dispatches to `action()`.
- `action.ts` — core upsert logic via cheerio. `reorderTableRows` groups `<tr id="preview-link-<env>-<service>">` rows by environment with `rowspan` merging — non-obvious and the highest-edge-case area.
- `github.ts` — Octokit wrapper (`findExistingComment` / `updateComment` / `createComment`). Reads action inputs at module load (`getOctokit(getInput('token'))`), so tests must mock `@actions/core` and `@actions/github` *before* importing it.

## Commands

```bash
yarn check # Biome — fails on warnings
yarn check:fix # auto-fix lint + format
yarn types:check # tsc --noEmit
yarn test:cov # vitest run --coverage (gate: 75% lines/statements)
yarn build # rimraf dist/ && node build.mjs (esbuild → dist/index.mjs)
```

## Conventions

- Biome enforces single quotes, 2-space, LF — no ESLint, Prettier, Husky, or lint-staged.
- Conventional Commits via commitlint (`commit-msg` hook). Use `feat!:` or a `BREAKING CHANGE:` footer to trigger a semantic-release major bump.
- Pre-commit auto-restages Biome fixes and runs `tsc --noEmit`. Never `--no-verify` — fix the underlying issue.
- Relative imports use the `.js` extension; Node built-ins use the `node:` protocol.
- `dist/` is gitignored on `main`. The release workflow rebuilds `dist/index.mjs` and force-commits it to the `v<major>` branch on each release — do not edit `dist/` by hand.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See [AGENTS.md](./AGENTS.md).
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: replace-comment-html
description: This action upserts HTML in GitHub issue or pull request comments using CSS selectors
author: Hunter Tunnicliff
runs:
using: node20
main: dist/index.js
using: node24
main: dist/index.mjs
inputs:
token:
description: GitHub token
Expand Down
Loading
Loading