diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 080c587..e458c4b 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -13,13 +13,15 @@ jobs: env: WORKING_DIRECTORY: ./ steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 20.19.4 - cache: "yarn" - cache-dependency-path: "${{ env.WORKING_DIRECTORY }}/yarn.lock" + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: '${{ env.WORKING_DIRECTORY }}/yarn.lock' - name: Install dependencies run: yarn install @@ -32,13 +34,15 @@ jobs: env: WORKING_DIRECTORY: ./ steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v4.1.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 20.19.4 - cache: "yarn" - cache-dependency-path: "${{ env.WORKING_DIRECTORY }}/yarn.lock" + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: '${{ env.WORKING_DIRECTORY }}/yarn.lock' - name: Install dependencies run: yarn install diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..6bc1010 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,87 @@ +name: Publish + +on: + release: + types: [published] + workflow_dispatch: + +# Read-only by default; the publish job opts into `packages: write`. +permissions: + contents: read + +concurrency: + group: publish-${{ github.event.release.tag_name || github.ref_name }} + cancel-in-progress: false + +jobs: + publish: + name: Publish to GitHub Packages + runs-on: ubuntu-latest + permissions: + contents: read # checkout + packages: write # npm publish to npm.pkg.github.com + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + persist-credentials: false + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version-file: '.nvmrc' + registry-url: 'https://npm.pkg.github.com' + scope: '@copia-automation' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Lint + run: yarn lint + + - name: Build + run: yarn build + + - name: Test + run: yarn test + + - name: Publish + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PUBLISH_NEXT: ${{ (github.event_name == 'workflow_dispatch' || github.event.release.prerelease) && 'true' || 'false' }} + run: | + NAME="$(node -p 'require("./package.json").name')" + VERSION="$(node -p 'require("./package.json").version')" + + # Build metadata (`+sha.1234`) may contain a hyphen, so strip it before + # testing for a SemVer prerelease suffix, e.g. 4.1.0-rc.1. + if [[ "${VERSION%%+*}" == *-* ]]; then + IS_PRERELEASE=true + else + IS_PRERELEASE=false + fi + + if [ "$PUBLISH_NEXT" != 'true' ]; then + # `latest` must only ever point at a stable version. + if [ "$IS_PRERELEASE" = 'true' ]; then + echo "::error::Refusing to publish prerelease version $VERSION to the latest tag; bump package.json to a stable version first." + exit 1 + fi + + npm publish --tag latest + exit 0 + fi + + # `next` must only ever point at a prerelease version. + if [ "$IS_PRERELEASE" != 'true' ]; then + echo "::error::Refusing to publish stable version $VERSION to the next tag; bump package.json to a prerelease version first." + exit 1 + fi + + # A manual run on an already-published prerelease only moves the tag. + if npm view "$NAME@$VERSION" version >/dev/null 2>&1; then + echo "$NAME@$VERSION is already published; retagging as next." + npm dist-tag add "$NAME@$VERSION" next + else + npm publish --tag next + fi diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..60ade1a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24.19.0 diff --git a/README.md b/README.md index 419a4ac..7054568 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ## Copia Notes -This fork contains a small modification. The ReactDiffView component now has an added `renderNodeWrapper` property, which is a function to render the diff nodes (aka table rows) with a wrapper. + +This fork contains a small modification. The ReactDiffView component now has an added `renderNodeWrapper` property, which is a function to render the diff nodes (aka table rows) with a wrapper. Keep in mind that since this package isn't published to npm, any modifications need to be built using `npm run build` and commited to this repo. @@ -31,8 +32,8 @@ npm i react-diff-viewer ## Usage ```javascript -import React, { PureComponent } from 'react'; -import ReactDiffViewer from 'react-diff-viewer'; +import React, { PureComponent } from 'react' +import ReactDiffViewer from 'react-diff-viewer' const oldCode = ` const a = 10 @@ -44,7 +45,7 @@ if(a > 10) { } console.log('done') -`; +` const newCode = ` const a = 10 const boo = 10 @@ -52,14 +53,14 @@ const boo = 10 if(a === 10) { console.log('bar') } -`; +` class Diff extends PureComponent { render = () => { return ( - ); - }; + ) + } } ``` @@ -106,8 +107,8 @@ An example using [Prism JS](https://prismjs.com) ``` ```javascript -import React, { PureComponent } from 'react'; -import ReactDiffViewer from 'react-diff-viewer'; +import React, { PureComponent } from 'react' +import ReactDiffViewer from 'react-diff-viewer' const oldCode = ` const a = 10 @@ -119,7 +120,7 @@ if(a > 10) { } console.log('done') -`; +` const newCode = ` const a = 10 const boo = 10 @@ -127,17 +128,17 @@ const boo = 10 if(a === 10) { console.log('bar') } -`; +` class Diff extends PureComponent { - highlightSyntax = str => ( + highlightSyntax = (str) => (
-  );
+  )
 
   render = () => {
     return (
@@ -147,8 +148,8 @@ class Diff extends PureComponent {
         splitView={true}
         renderContent={this.highlightSyntax}
       />
-    );
-  };
+    )
+  }
 }
 ```
 
@@ -169,22 +170,22 @@ enum DiffMethod {
 ```
 
 ```javascript
-import React, { PureComponent } from 'react';
-import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer';
+import React, { PureComponent } from 'react'
+import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer'
 
 const oldCode = `
 {
   "name": "Original name",
   "description": null
 }
-`;
+`
 const newCode = `
 {
   "name": "My updated name",
   "description": "Brand new description",
   "status": "running"
 }
-`;
+`
 
 class Diff extends PureComponent {
   render = () => {
@@ -195,8 +196,8 @@ class Diff extends PureComponent {
         compareMethod={DiffMethod.WORDS}
         splitView={true}
       />
-    );
-  };
+    )
+  }
 }
 ```
 
@@ -293,8 +294,8 @@ To override any style, just pass the new style object to the `styles` prop. New
 For keys other than `variables`, the value can either be an object or string interpolation.
 
 ```javascript
-import React, { PureComponent } from 'react';
-import ReactDiffViewer from 'react-diff-viewer';
+import React, { PureComponent } from 'react'
+import ReactDiffViewer from 'react-diff-viewer'
 
 const oldCode = `
 const a = 10
@@ -306,7 +307,7 @@ if(a > 10) {
 }
 
 console.log('done')
-`;
+`
 const newCode = `
 const a = 10
 const boo = 10
@@ -314,33 +315,33 @@ const boo = 10
 if(a === 10) {
   console.log('bar')
 }
-`;
+`
 
 class Diff extends PureComponent {
-  highlightSyntax = str => (
+  highlightSyntax = (str) => (
     
-  );
+  )
 
   render = () => {
     const newStyles = {
       variables: {
         dark: {
           highlightBackground: '#fefed5',
-          highlightGutterBackground: '#ffcd3c',
-        },
+          highlightGutterBackground: '#ffcd3c'
+        }
       },
       line: {
         padding: '10px 2px',
         '&:hover': {
-          background: '#a26ea1',
-        },
-      },
-    };
+          background: '#a26ea1'
+        }
+      }
+    }
 
     return (
       
-    );
-  };
+    )
+  }
 }
 ```
 
@@ -369,20 +370,20 @@ Check package.json for more build scripts.
 
 MIT
 
-## Publish this package to github package registry
-
-1. Run `yarn build`
-2. Generate a Personal Access Token (PAT)
-  a. Navigate to "github.com" > "settings"
-  b. Click on "Developer Settings"
-  c. Click on "Personal Access Tokens"
-  d. Click on "Tokens (classic)"
-  e. Click on "Generate New Token"
-  f. Enable read/write packages and create token
-  g. Save the token to 1password
-3. In your cli enter: `npm login --registry=https://npm.pkg.github.com`
-4. Enter your github username
-5. Enter your new PAT as the password
-6. If prompted, enter your email
-7. Version and run `npm publish`
-8. Navigate to the copia-automation package repository to view your package: https://github.com/copia-automation/acd-parser/pkgs/npm/acd-parser
+## Releasing
+
+Publishing to the GitHub package registry is automated by
+[`.github/workflows/publish.yml`](.github/workflows/publish.yml).
+
+1. Bump the `version` field in `package.json` and open a PR.
+2. Merge the PR to `main`.
+3. Create a [GitHub release](https://github.com/copia-automation/react-diff-viewer/releases/new)
+   targeting `main` with a new tag matching the version you just merged — `v` or
+   `` both work. Publish the release.
+4. The `Publish` workflow lints, builds, tests, and runs `npm publish`. Watch it in the
+   [Actions tab](https://github.com/copia-automation/react-diff-viewer/actions/workflows/publish.yml).
+5. The published package appears at
+   https://github.com/copia-automation/react-diff-viewer/pkgs/npm/react-diff-viewer.
+
+Releases marked as a pre-release publish under the `next` dist-tag instead of `latest`, so they
+won't be installed by default.
diff --git a/package.json b/package.json
index 53e75b7..9405aa8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@copia-automation/react-diff-viewer",
-  "version": "4.0.6",
+  "version": "4.0.7",
   "private": false,
   "description": "A simple and beautiful text diff viewer component made with diff and React",
   "keywords": [
@@ -24,6 +24,10 @@
   },
   "license": "MIT",
   "author": "Copia Automation (originally Pranesh Ravi )",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/copia-automation/react-diff-viewer.git"
+  },
   "main": "lib/index",
   "typings": "lib/index",
   "scripts": {
diff --git a/src/compute-lines.ts b/src/compute-lines.ts
index 76ad046..751ffdc 100644
--- a/src/compute-lines.ts
+++ b/src/compute-lines.ts
@@ -269,9 +269,14 @@ const computeLineInformation = (
         right.value = line;
       }
 
-      counter += 1;
-
+      // `counter` tracks the index of the line inside `lineInformation`, which
+      // is what `diffLines` records. The lookahead pass (`isRetrieveNext`) only
+      // borrows the right side of an already-counted modification line, so it
+      // must not advance the counter - otherwise `diffLines` drifts ahead of
+      // the real line indexes by one for every modification, which pushes the
+      // "Expand x lines ..." indicator below the diff block it belongs to.
       if (!isRetrieveNext) {
+        counter += 1;
         lineInformation.push({
           left,
           right,
diff --git a/test/compute-lines.test.ts b/test/compute-lines.test.ts
index b026120..e32589c 100644
--- a/test/compute-lines.test.ts
+++ b/test/compute-lines.test.ts
@@ -260,7 +260,7 @@ Also this info`;
           left: {},
         },
       ],
-      diffLines: [0, 2],
+      diffLines: [0, 1],
     });
   });
 
@@ -304,7 +304,7 @@ Also this info`;
           left: {},
         },
       ],
-      diffLines: [0, 2],
+      diffLines: [0, 1],
     });
   });
 
@@ -336,7 +336,7 @@ Also this info`;
           left: {},
         },
       ],
-      diffLines: [0, 2],
+      diffLines: [0, 1],
     });
   });
 
@@ -370,7 +370,7 @@ Also this info`;
           left: {},
         },
       ],
-      diffLines: [0, 2],
+      diffLines: [0, 1],
     });
   });
 });