Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: streamline package publishing #453

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 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
32 changes: 16 additions & 16 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: "monthly"
interval: 'monthly'
labels:
- "dependencies"
- "npm"
- "skip changelog"
- 'dependencies'
- 'npm'
- 'skip changelog'
groups:
production-dependencies:
dependency-type: "production"
dependency-type: 'production'
update-types:
- "minor"
- "patch"
- 'minor'
- 'patch'
dev-dependencies:
dependency-type: "development"
dependency-type: 'development'
update-types:
- "minor"
- "patch"
- 'minor'
- 'patch'
ignore:
# We want @types/node to match the *lowest* version of node.js that we support
- dependency-name: "@types/node"
- dependency-name: '@types/node'
update-types:
- "version-update:semver-major"
- "version-update:semver-minor"
- 'version-update:semver-major'
- 'version-update:semver-minor'
# As a library, upgrading TypeScript and using new language features would
# be a breaking change for users who have not yet upgraded their TS version
- dependency-name: "typescript"
- dependency-name: 'typescript'
6 changes: 2 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Run Linter
run: npm run eslint
- name: Run Formatter
run: npm run prettier
run: npm run prettier -- --check

test:
name: Test - ${{ matrix.node-version }}
Expand Down Expand Up @@ -62,10 +62,8 @@ jobs:
run: npm ci
- name: Build
run: npm run build
- name: Extract API
run: npm run api:extract
- name: Generate docs
run: npm run api:docs
run: npm run docs:ci
- name: Ensure API and doc changes have been committed
run: |
git add --renormalize .
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Publish

on:
release:
types: [published]

permissions:
contents: read

jobs:
publish:
name: Publish to NPM
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- run: npm ci
- run: npm run prettier -- --check
- run: npm run lint
- run: npm run build
- run: npm run docs:ci
- name: Validate up-to-date documentation
run: |
git add --renormalize .
if (( "$(git diff HEAD --ignore-space-at-eol --ignore-cr-at-eol | wc -l)" != 0 )); then
cat << EOF >> $GITHUB_STEP_SUMMARY
### Detected uncommitted changes

\`\`\`shell
$(git diff HEAD)
\`\`\`
EOF
git diff HEAD
exit 1
fi

- run: npm test
- run: npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist
test
api
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Changelog

All notable changes to this project can be found at on the [Releases](https://github.com/salesforce/tough-cookie/releases)
All notable changes to this project can be found on the [GitHub Releases](https://github.com/salesforce/tough-cookie/releases)
page.
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ yarn add tough-cookie
import { Cookie, CookieJar } from 'tough-cookie'

// parse a `Cookie` request header
const reqCookies = 'ID=298zf09hf012fh2; csrf=u32t4o3tb3gg43; _gat=1'.split(';').map(Cookie.parse)
const reqCookies = 'ID=298zf09hf012fh2; csrf=u32t4o3tb3gg43; _gat=1'
.split(';')
.map(Cookie.parse)
// generate a `Cookie` request header
const cookieHeader = reqCookies.map(cookie => cookie.cookieString()).join(';')
const cookieHeader = reqCookies.map((cookie) => cookie.cookieString()).join(';')

// parse a Set-Cookie response header
const resCookie = Cookie.parse('foo=bar; Domain=example.com; Path=/; Expires=Tue, 21 Oct 2025 00:00:00 GMT')
const resCookie = Cookie.parse(
'foo=bar; Domain=example.com; Path=/; Expires=Tue, 21 Oct 2025 00:00:00 GMT',
)
// generate a Set-Cookie response header
const setCookieHeader = cookie.toString()

Expand Down Expand Up @@ -58,8 +62,14 @@ import { CookieJar } from 'tough-cookie'
const cookieJar = new CookieJar() // uses the in-memory store by default

// storing cookies with various SameSite attributes
await cookieJar.setCookie('strict=authorized; SameSite=strict', 'http://example.com/index.html')
await cookieJar.setCookie('lax=okay; SameSite=lax', 'http://example.com/index.html')
await cookieJar.setCookie(
'strict=authorized; SameSite=strict',
'http://example.com/index.html',
)
await cookieJar.setCookie(
'lax=okay; SameSite=lax',
'http://example.com/index.html',
)
await cookieJar.setCookie('normal=whatever', 'http://example.com/index.html')

// retrieving cookies using a SameSite context
Expand Down Expand Up @@ -105,7 +115,7 @@ You can define this functionality by passing in the `prefixSecurity` option to `
import { CookieJar, MemoryCookieStore } from 'tough-cookie'

const cookieJar = new CookieJar(new MemoryCookieStore(), {
prefixSecurity: 'silent'
prefixSecurity: 'silent',
})

// this cookie will be silently ignored since the url is insecure (http)
Expand Down
6 changes: 3 additions & 3 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { JestConfigWithTsJest } from "ts-jest";
import type { JestConfigWithTsJest } from 'ts-jest'

const config: JestConfigWithTsJest = {
preset: 'ts-jest',
testEnvironment: 'node',
rootDir: './lib/',
testPathIgnorePatterns: ['./lib/__tests__/data/'],
fakeTimers: {
enableGlobally: true
}
enableGlobally: true,
},
}

export default config
3 changes: 2 additions & 1 deletion lib/__tests__/cookieJar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { CookieJar } from '../cookie/cookieJar'
import type { SerializedCookieJar } from '../cookie/constants'
import { MemoryCookieStore } from '../memstore'
import { Store } from '../store'
import { version } from '../version'

// ported from:
// - test/api_test.js (cookie jar tests)
Expand Down Expand Up @@ -977,7 +978,7 @@ describe('CookieJar', () => {
prefixSecurity: 'silent',
rejectPublicSuffixes: true,
storeType: 'MemoryCookieStore',
version: 'tough-cookie@5.0.0',
version: `tough-cookie@${version}`,
}
expect(data).toEqual(expected)
},
Expand Down
4 changes: 0 additions & 4 deletions lib/__tests__/jarSerialization.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ import { Store } from '../store'
import { version } from '../version'

describe('cookieJar serialization', () => {
it('should use the expected version', () => {
expect(version).toBe('5.0.0')
})

it('should provide the list of serialized properties available for a Cookie with `Cookie.serializableProperties`', () => {
expect(Cookie.serializableProperties).toEqual([
'key',
Expand Down
8 changes: 8 additions & 0 deletions lib/__tests__/version.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { version } from '../version'

describe('version file', () => {
it('should have a valid semver version', () => {
expect(typeof version).toBe('string')
expect(version).toMatch(/^\d+?\.\d+?\.\d+?(?:-[\w.]+?)?$/)
})
})
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,22 @@
"!__tests__"
],
"scripts": {
"api:dev": "npm run build && npm run api:extract -- --local && npm run api:docs",
"api:docs": "api-documenter markdown --input-folder ./tmp --output-folder ./api/docs",
"api:extract": "api-extractor run --verbose",
"docs": "npm run build && npm run docs:ci",
"docs:ci": "npm run docs:extract -- --local && npm run docs:generate",
"docs:generate": "api-documenter markdown --input-folder ./tmp --output-folder ./api/docs",
"docs:extract": "api-extractor run --verbose",
Comment on lines +95 to +98
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I agree with this specific renaming. There are actually two distinct processes happening here:

  1. Public API metadata is extracted from the code
  2. Documentation is generated from the code

If we're going to rename, we should probably use names that reflect these different processes so we don't conflate them as I originally did.

Also, we shouldn't use pass --local in the docs:ci script. That flag disables the validation which checks if the public API has changed. The API report that api-extractor produces should be thought of as similar to package-lock.json only it's a lockfile for public API changes, not dependencies. Following that comparison, consider the workflow for package-lock.json:

  • Changes are deliberately made to the lockfile by a developer (or dependabot) locally and then the change is committed
  • When running npm ci in an automated environment, if the lockfile doesn't match package.json then it will error

We should follow a similar process for the API report. That is how the previous scripts operated with api:dev being the deliberate, local change and api:extract being the automated one which should fail if there is a difference detected.

"build": "npm run clean && tsc",
"clean": "rm -rf dist",
"version": "genversion --template version-template.ejs --force lib/version.ts && git add lib/version.ts",
"version:version-file": "genversion --template version-template.ejs --force lib/version.ts",
"version": "npm run version:version-file && npm run docs && git add ./lib/version.ts ./api/docs",
"test": "npm run test:ts && npm run test:legacy",
"test:ts": "jest",
"test:legacy": "npm run build -- --declaration false && ./test/scripts/vows.js test/*_test.js",
"typecheck": "tsc --noEmit",
"cover": "jest --coverage",
"lint": "eslint .",
"eslint": "eslint .",
"prettier": "prettier '**/*.{json,ts,yaml,md}'",
"prettier": "prettier .",
"format": "npm run eslint -- --fix"
},
"//": "We only support node 18+, but v16 still works. We won't block v16 until it becomes a burden.",
Expand Down