Skip to content

ESRP: support multiple users, clarify docs, retry transient submit failures - #1412

Open
Elizabeth Craig (ecraig12345) wants to merge 3 commits into
mainfrom
esrp-multi-user
Open

Elizabeth Craig (ecraig12345) wants to merge 3 commits into
mainfrom
esrp-multi-user

Conversation

@ecraig12345

Copy link
Copy Markdown
Member
  • Update ESRP_USER to accept multiple user emails, and clarify where DLs are and are not allowed
  • Clarify internal types about what API properties appear to be required or optional
  • Retry a transient release submit failure up to 3 times
  • Reclassify an azure storage response parse error as non-retryable

Copilot AI balanced review requested due to automatic review settings September 12, 2026 04:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

PARSE_ERROR can still be retried with a transient status code, and regression coverage is incomplete.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR enhances the ESRP npm release helper with multi-user configuration, clearer API documentation, base64 file hashes, and transient submission retries.

Changes:

  • Supports comma-separated ESRP_USER values and clarifies contact restrictions.
  • Refines ESRP API types and JWS/hash handling.
  • Adds three-attempt submit retries and updates parse-error classification.
  • Updates documentation, tests, and change records.
File summaries
File Description
packages/esrp-npm-release/src/utils/getEnvOptions.ts Parses multiple fallback users.
packages/esrp-npm-release/src/utils/errorHelpers.ts Updates retry classification.
packages/esrp-npm-release/src/types/EnvOptions.ts Clarifies contact restrictions.
packages/esrp-npm-release/src/types/api.ts Refines ESRP API types.
packages/esrp-npm-release/src/esrpApi/releaseHttp.ts Adds transient submission retries.
packages/esrp-npm-release/src/esrpApi/npmRelease.ts Uses base64 file hashes.
packages/esrp-npm-release/src/auth/generateJwsToken.ts Adds typed JWS headers.
packages/esrp-npm-release/src/__tests__/releaseHttp.test.ts Tests submission retries.
packages/esrp-npm-release/src/__tests__/npmRelease.test.ts Updates hash and logging tests.
packages/esrp-npm-release/src/__tests__/getEnvOptions.test.ts Tests multiple fallback users.
packages/esrp-npm-release/src/__tests__/generateJwsToken.test.ts Updates JWS type tests.
packages/esrp-npm-release/src/__tests__/errorHelpers.test.ts Updates retry classification tests.
packages/esrp-npm-release/README.md Documents configuration and contact changes.
change/@microsoft-esrp-npm-release-b7d0e7c6-9f2a-49e5-b785-7fbd783c8eca.json Records retry behavior changes.
change/@microsoft-esrp-npm-release-b66dea30-7381-4b55-a98b-a0b79dc9c08a.json Records user and documentation changes.
Review details

Suppressed comments (1)

packages/esrp-npm-release/src/tests/errorHelpers.test.ts:23

  • The changed classification removes PARSE_ERROR from the retryable cases, but this replacement test only exercises REQUEST_SEND_ERROR, so a regression could silently make parse failures retryable again. Add an assertion that RestError.PARSE_ERROR is non-retryable.
  it('retries pipeline error REQUEST_SEND_ERROR', () => {
    expect(isRetryableAzureError(new RestError('pipeline failure', { code: RestError.REQUEST_SEND_ERROR }))).toBe(true);
  • Files reviewed: 15/15 changed files
  • Comments generated: 1
  • Review effort level: Lite (auto)

Note

Copilot is running an experiment and ran this review at Lite.


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/esrp-npm-release/src/utils/errorHelpers.ts
Copilot AI review requested due to automatic review settings September 12, 2026 05:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Retries may duplicate release operations without an idempotency guarantee, and regression coverage remains incomplete.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

packages/esrp-npm-release/src/tests/errorHelpers.test.ts:23

  • The old parameterized case explicitly covered RestError.PARSE_ERROR; removing it leaves the new non-retryable classification untested. Add a regression assertion for a parse error without a status so this retry-safety rule cannot regress.
  it('retries pipeline error REQUEST_SEND_ERROR', () => {
    expect(isRetryableAzureError(new RestError('pipeline failure', { code: RestError.REQUEST_SEND_ERROR }))).toBe(true);

packages/esrp-npm-release/src/tests/releaseHttp.test.ts:65

  • Because this scenario succeeds on the third mocked request, it would also pass if maxAttempts were 4 or unbounded. Add an all-transient-failures case that asserts the submit stops after exactly three fetches and returns the wrapped ReleaseError, so the new hard attempt limit is covered.
    it('retries transient failures up to three attempts', async () => {
      jest.useFakeTimers();
      fetchMock
        .mockResolvedValueOnce(makeFetchResponse({ status: 503, body: 'unavailable' }))
        .mockRejectedValueOnce(new Error('fetch failed'))
        .mockResolvedValueOnce(makeFetchResponse({ body: '{"operationId":"op-1"}' }));

      const promise = submitRelease({ ...defaultParams, releaseRequest: mockRequest });
      await jest.runAllTimersAsync();

      await expect(promise).resolves.toEqual({ operationId: 'op-1' });
      expect(fetchMock).toHaveBeenCalledTimes(3);
  • Files reviewed: 15/15 changed files
  • Comments generated: 2
  • Review effort level: Lite (auto)

Note

Copilot is running an experiment and ran this review at Lite.

bearerToken,
method: 'POST',
body: releaseRequest,
maxAttempts: 3,
Comment thread packages/esrp-npm-release/src/utils/errorHelpers.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants