Skip to content

Commit 60c1fe6

Browse files
committed
fix: Refactor to generic RSS parser with Cheerio
Replaces xml2js-based parsing with a generic Cheerio-powered RSS parser. Adds type-safe selector maps, new helpers for Substack and Goodreads feeds, and improves error handling. Updates README and type definitions, introduces new tests, and adds Cheerio as a dependency. Updates GitHub workflows for versioning and release, and adds a version check workflow.
1 parent c8121ec commit 60c1fe6

24 files changed

Lines changed: 2461 additions & 1948 deletions

.env.copy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
VITE_PROXY_SUBSTACK_ORIGIN=xxxx
2+
VITE_PROXY_SUBSTACK_PATH=xxxx
3+
VITE_PROXY_GOODREADS_ORIGIN=xxxx
4+
VITE_PROXY_GOODREADS_PATH=xxxx

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88

99
## Checklist
1010

11+
- [ ] This PR targets a release branch named `release/patch`, `release/minor`, or `release/major` as appropriate.
12+
- [ ] `package.json` has been bumped with the correct semver increment for this release.
13+
- [ ] `package-lock.json` (and any other lockfiles) have been updated and match the version in `package.json`.
1114
- [ ] The code follows the repository's coding standards and style guidelines.
1215
- [ ] All tests have been written or updated to cover the changes in this PR.
1316
- [ ] The code passes all existing tests.
1417
- [ ] Documentation has been updated to reflect any changes in functionality.
1518
- [ ] Any new dependencies have been documented (if applicable).
1619
- [ ] Any necessary migration steps have been outlined (if applicable).
1720
- [ ] The code has been reviewed by at least one other team member.
18-
- [ ] The branch is up-to-date with the latest changes from the main/master branch.
21+
- [ ] The branch is up-to-date with the latest changes from the main branch.
1922

2023
## Testing Instructions
2124

.github/workflows/bump_version.yml

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,80 @@
1-
name: Bump version, commit and push tag
2-
# This workflow is triggered on push to a release branch (release/patch, release/minor, release/major).
3-
# It uses the npm-get-version-action to get the current version from package.json and bumps the version based on the branch name.
4-
# It also commits the changes made to package.json and pushes the tag to the repository.
1+
name: Prepare release version
2+
53
on:
64
push:
75
branches:
8-
- 'release/*'
9-
workflow_call:
6+
- release/**
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: bump-version-${{ github.ref }}
11+
cancel-in-progress: false
12+
1013
jobs:
11-
bump_version:
12-
# Only run if the PR is from a release branch (release/patch, release/minor, release/major)
13-
if: ${{ github.ref_name == 'release/patch' || github.ref_name == 'release/minor' || github.ref_name == 'release/major' }}
14+
bump:
15+
name: Bump package version
1416
runs-on: ubuntu-latest
15-
strategy:
16-
matrix:
17-
node-version: [ 20.x ]
17+
permissions:
18+
contents: write
1819
steps:
19-
# Checkout the repo
20-
- uses: actions/checkout@v4
21-
# Setup node
22-
- uses: actions/setup-node@v4
20+
- name: Validate release branch naming
21+
run: |
22+
case "${GITHUB_REF_NAME}" in
23+
release/patch|release/minor|release/major)
24+
echo "Release branch ${GITHUB_REF_NAME} accepted."
25+
;;
26+
*)
27+
echo "Invalid release branch name: ${GITHUB_REF_NAME}"
28+
exit 1
29+
;;
30+
esac
31+
32+
- name: Checkout repository
33+
uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0
36+
37+
- name: Use Node.js
38+
uses: actions/setup-node@v4
2339
with:
24-
node-version: ${{ matrix.node-version }}
40+
node-version: 20
2541

2642
- name: Install dependencies
27-
run: npm install
43+
run: npm ci
2844

29-
- name: Setup Git user
45+
- name: Run unit tests
46+
run: npm test --if-present
47+
48+
- name: Determine bump type
49+
id: bump
3050
run: |
31-
git config user.name "GitHub Actions"
32-
git config user.email "actions@github.com"
51+
case "${GITHUB_REF_NAME}" in
52+
release/patch) echo "type=patch" >>"$GITHUB_OUTPUT" ;;
53+
release/minor) echo "type=minor" >>"$GITHUB_OUTPUT" ;;
54+
release/major) echo "type=major" >>"$GITHUB_OUTPUT" ;;
55+
esac
3356
34-
- name: Check for uncommitted changes
57+
- name: Configure git author
3558
run: |
36-
if [ -n "$(git status --porcelain)" ]; then
37-
echo "Uncommitted changes detected. Committing..."
38-
git add .
39-
git commit -m "Pre-version bump changes"
40-
else
41-
echo "Working directory clean. Proceeding with version bump."
42-
fi
59+
git config user.name "github-actions[bot]"
60+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
4361
44-
- name: Bump version patch
45-
if: github.ref == 'refs/heads/release/patch'
46-
run: npm run version:patch && git push --follow-tags
62+
- name: Bump package version
63+
run: |
64+
npm version ${{ steps.bump.outputs.type }} --no-git-tag-version --commit-hooks false
65+
VERSION="$(node -p "require('./package.json').version")"
66+
echo "version=${VERSION}" >>"$GITHUB_OUTPUT"
67+
id: version
4768

48-
- name: Bump version minor
49-
if: github.ref == 'refs/heads/release/minor'
50-
run: npm run version:minor && git push --follow-tags
69+
- name: Commit version bump
70+
run: |
71+
if git status --porcelain | grep .; then
72+
git add package.json package-lock.json
73+
git commit -m "chore: bump version to v${{ steps.version.outputs.version }}"
74+
else
75+
echo "No changes to commit."
76+
fi
5177
52-
- name: Bump version major
53-
if: github.ref == 'refs/heads/release/major'
54-
run: npm run version:major && git push --follow-tags
78+
- name: Push changes
79+
if: github.ref_protected != 'true'
80+
run: git push --set-upstream origin "${GITHUB_REF_NAME}"

.github/workflows/ci.yml

Lines changed: 99 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,112 @@
1-
name: CI
2-
# This workflow is triggered on push to the main branch.
3-
# It uses the npm-get-version-action to get the current version from package.json and creates a GitHub release from the latest tag.
4-
# It also publishes the package to NPM.
1+
name: Release
2+
53
on:
64
push:
75
branches:
8-
- 'main'
6+
- main
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: release-main
11+
cancel-in-progress: false
12+
913
jobs:
10-
build:
14+
publish:
15+
name: Publish package and tag release
1116
runs-on: ubuntu-latest
1217
permissions:
1318
contents: write
14-
strategy:
15-
matrix:
16-
node-version: [ 20.x ]
19+
packages: write
20+
id-token: write # Required for npm trusted publishing (OIDC)
1721
steps:
18-
# Checkout the repo
19-
- uses: actions/checkout@v4
20-
with :
21-
ref: ${{ github.refs }}
22-
# Setup node
23-
- uses: actions/setup-node@v4
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
2424
with:
25-
node-version: ${{ matrix.node-version }}
26-
# Add the registry URL to publish to NPM (optional)
27-
registry-url: 'https://registry.npmjs.org'
28-
# Add the scope of the package to publish to NPM (optional)
29-
scope: '@rohit1901'
30-
# Install dependencies
25+
fetch-depth: 0
26+
27+
- name: Use Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: 24
31+
registry-url: https://registry.npmjs.org
32+
3133
- name: Install dependencies
32-
if: ${{ success() }}
33-
run: npm install
34-
# Get the current version from package.json
35-
- name: Get the current version from package.json
36-
id: package-version
37-
uses: martinbeentjes/npm-get-version-action@v1.3.1
38-
# Build the project
39-
- name: Build the project
40-
if: ${{ success() }}
34+
run: npm ci
35+
36+
- name: Run tests
37+
run: npm test --if-present
38+
39+
- name: Build package
4140
run: npm run build
42-
# Create a GitHub release
43-
- name: Create a GitHub Release from the latest tag
44-
if: ${{ success() }}
45-
run: gh release create v${{ steps.package-version.outputs.current-version }}
41+
42+
- name: Determine package metadata
43+
id: pkg
44+
run: |
45+
node <<'NODE' >> "$GITHUB_OUTPUT"
46+
const pkg = require('./package.json');
47+
console.log(`name=${pkg.name}`);
48+
console.log(`version=${pkg.version}`);
49+
NODE
50+
51+
- name: Check npm registry for existing version
52+
id: registry
4653
env:
47-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48-
# Publish to NPM
49-
- name: Publish to NPM
50-
if: ${{ success() }}
51-
run: npm publish --access public
54+
PACKAGE: ${{ steps.pkg.outputs.name }}
55+
VERSION: ${{ steps.pkg.outputs.version }}
56+
run: |
57+
if npm view "${PACKAGE}@${VERSION}" version >/dev/null 2>&1; then
58+
echo "Version ${PACKAGE}@${VERSION} already exists on the npm registry."
59+
echo "registry_has_version=true" >> "$GITHUB_OUTPUT"
60+
else
61+
echo "Version ${PACKAGE}@${VERSION} not found on the npm registry."
62+
echo "registry_has_version=false" >> "$GITHUB_OUTPUT"
63+
fi
64+
65+
- name: Ensure git tag exists
66+
id: tag
5267
env:
53-
NODE_AUTH_TOKEN: ${{secrets.NPM_PUBLISH_TOKEN}}
68+
TAG: v${{ steps.pkg.outputs.version }}
69+
run: |
70+
if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
71+
echo "Tag ${TAG} already exists."
72+
echo "tag_exists=true" >> "$GITHUB_OUTPUT"
73+
else
74+
git tag "${TAG}"
75+
git push origin "${TAG}"
76+
echo "tag_exists=false" >> "$GITHUB_OUTPUT"
77+
fi
78+
79+
- name: Write release summary
80+
run: |
81+
{
82+
echo "## Release pipeline"
83+
echo "- Package: \`${{ steps.pkg.outputs.name }}\`"
84+
echo "- Version: \`v${{ steps.pkg.outputs.version }}\`"
85+
if [ "${{ steps.tag.outputs.tag_exists }}" = "true" ]; then
86+
echo "- Git tag: already existed (reusing existing tag)"
87+
else
88+
echo "- Git tag: created for this run"
89+
fi
90+
if [ "${{ steps.registry.outputs.registry_has_version }}" = "true" ]; then
91+
echo "- Registry: version already published (publish will be skipped)"
92+
else
93+
echo "- Registry: version not yet published"
94+
fi
95+
echo "- Authentication: npm trusted publishing (OIDC)"
96+
} >> "$GITHUB_STEP_SUMMARY"
97+
98+
- name: Publish to npm
99+
if: steps.registry.outputs.registry_has_version != 'true'
100+
# No NODE_AUTH_TOKEN needed - uses OIDC via trusted publishing
101+
run: npm publish --access public --provenance
102+
103+
- name: Create GitHub release
104+
env:
105+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106+
TAG: v${{ steps.pkg.outputs.version }}
107+
run: |
108+
if gh release view "${TAG}" >/dev/null 2>&1; then
109+
echo "Release ${TAG} already exists."
110+
else
111+
gh release create "${TAG}" --title "${TAG}" --generate-notes
112+
fi

0 commit comments

Comments
 (0)