Skip to content
Open
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
21 changes: 21 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://unpkg.com/@changesets/config/schema.json",
"changelog": [
"@changesets/changelog-github",
{
"repo": "braintrustdata/braintrust-sdk-javascript"
}
],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"bumpVersionsWithWorkspaceProtocolOnly": true,
"ignore": [],
"snapshot": {
"useCalculatedVersion": true,
"prereleaseTemplate": "{tag}.{datetime}.{commit}"
}
}
159 changes: 159 additions & 0 deletions .github/workflows/_run-js-release-mode.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: Run JS release mode

on:
workflow_call:
inputs:
mode:
required: true
type: string
checkout_ref:
required: true
type: string
version_command:
required: true
type: string
publish_enabled:
required: false
default: false
type: boolean
publish_command:
required: false
default: ""
type: string
artifact_dir:
required: false
default: ""
type: string
artifact_name:
required: false
default: ""
type: string
slack_text:
required: false
default: ""
type: string
slack_header:
required: false
default: ""
type: string
slack_details:
required: false
default: ""
type: string
run_canary_check:
required: false
default: false
type: boolean

jobs:
run:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
actions: read
contents: read
id-token: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
ref: ${{ inputs.checkout_ref }}
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .tool-versions
cache: pnpm
registry-url: https://registry.npmjs.org
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Validate publishable package metadata
run: node scripts/release/validate-publishable-packages.mjs
- name: Compute changeset status
run: pnpm exec changeset status --output=.changeset-status.json
- name: Check release status
id: status_check
run: node scripts/release/check-changeset-status.mjs --mode ${{ inputs.mode }} --status-file .changeset-status.json
- name: Check if canary already published for HEAD
if: inputs.run_canary_check && steps.status_check.outputs.has_packages == 'true'
id: canary_check
env:
GITHUB_TOKEN: ${{ github.token }}
run: node scripts/release/should-publish-canary.mjs --status-file .changeset-status.json
- name: Decide whether to continue
id: plan
env:
HAS_PACKAGES: ${{ steps.status_check.outputs.has_packages }}
RUN_CANARY_CHECK: ${{ inputs.run_canary_check && 'true' || 'false' }}
CANARY_SHOULD_PUBLISH: ${{ steps.canary_check.outputs.should_publish }}
run: |
should_run="$HAS_PACKAGES"
reason="Packages are available."

if [ "$HAS_PACKAGES" != "true" ]; then
should_run=false
reason="No publishable packages found."
elif [ "$RUN_CANARY_CHECK" = "true" ] && [ "$CANARY_SHOULD_PUBLISH" != "true" ]; then
should_run=false
reason="Canary already published for HEAD."
fi

echo "should_run=$should_run" >> "$GITHUB_OUTPUT"

{
echo "## Release mode"
echo
echo '- Mode: `${{ inputs.mode }}`'
echo '- Ref: `${{ inputs.checkout_ref }}`'
echo "- Decision: $reason"
} >> "$GITHUB_STEP_SUMMARY"
- name: Version packages
if: steps.plan.outputs.should_run == 'true'
run: ${{ inputs.version_command }}
- name: Prepare release manifest
if: steps.plan.outputs.should_run == 'true'
run: node scripts/release/prepare-release-manifest.mjs --mode ${{ inputs.mode }} --status-file .changeset-status.json --output .release-manifest.json
- name: Build publishable packages
if: steps.plan.outputs.should_run == 'true'
run: bash scripts/release/build-publishable-packages.sh .release-manifest.json
- name: Publish packages
if: steps.plan.outputs.should_run == 'true' && inputs.publish_enabled
run: ${{ inputs.publish_command }}
env:
NPM_TOKEN: ""
- name: Summarize release
if: steps.plan.outputs.should_run == 'true'
id: summary
run: node scripts/release/summarize-release.mjs --mode ${{ inputs.mode }} --manifest .release-manifest.json
- name: Pack publishable packages
if: steps.plan.outputs.should_run == 'true' && inputs.artifact_dir != ''
run: node scripts/release/pack-publishable-packages.mjs --manifest .release-manifest.json --output-dir ${{ inputs.artifact_dir }}
- name: Upload dry-run artifacts
if: steps.plan.outputs.should_run == 'true' && inputs.artifact_dir != '' && inputs.artifact_name != ''
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ inputs.artifact_name }}
path: ${{ inputs.artifact_dir }}
retention-days: 5
- name: Post release to Slack
if: steps.plan.outputs.should_run == 'true' && inputs.slack_text != '' && inputs.slack_header != ''
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: C0ABHT0SWA2
text: "${{ inputs.slack_text }}"
blocks:
- type: "header"
text:
type: "plain_text"
text: "${{ inputs.slack_header }}"
- type: "section"
text:
type: "mrkdwn"
text: |
${{ inputs.slack_details }}
*Packages:*
${{ steps.summary.outputs.markdown }}

<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>
84 changes: 23 additions & 61 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ jobs:
- name: Ensure SHA pinned actions
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@ca46236c6ce584ae24bc6283ba8dcf4b3ec8a066 # v5.0.4

changeset-required:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .tool-versions
- name: Fetch pull request base ref
run: git fetch origin "${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}"
- name: Enforce changeset requirement for publishable package changes
run: node scripts/release/enforce-changeset.mjs

js-test:
runs-on: ${{ matrix.os }}
timeout-minutes: 30
Expand Down Expand Up @@ -131,72 +147,16 @@ jobs:
run: |
echo "Artifact: $ARTIFACT_NAME"
echo "name=$ARTIFACT_NAME" >> "$GITHUB_OUTPUT"
- name: Prepare artifact
id: prepare_artifact
working-directory: js
shell: bash
run: |
mkdir -p artifacts
PACKED_TARBALL=$(npm pack --pack-destination artifacts)
echo "packed_tarball=$PACKED_TARBALL" >> "$GITHUB_OUTPUT"
- name: Pack @braintrust/browser
id: prepare_browser_artifact
working-directory: integrations/browser-js
shell: bash
run: |
PACKED_BROWSER_TARBALL=$(npm pack --pack-destination ../../js/artifacts)
echo "packed_browser_tarball=$PACKED_BROWSER_TARBALL" >> "$GITHUB_OUTPUT"
- name: Build and pack @braintrust/otel
id: prepare_otel_artifact
shell: bash
run: |
BRAINTRUST_TARBALL=$(ls js/artifacts/braintrust-*.tgz | head -n 1)
if [ -z "$BRAINTRUST_TARBALL" ]; then
echo "Error: braintrust tarball not found"
exit 1
fi
echo "Using braintrust tarball: $BRAINTRUST_TARBALL"

cd integrations/otel-js
if ! npm_config_save=false npm_config_lockfile=false pnpm add \
file:../../$BRAINTRUST_TARBALL \
@opentelemetry/api@^1.9.0 \
@opentelemetry/core@^1.9.0 \
@opentelemetry/exporter-trace-otlp-http@^0.35.0 \
@opentelemetry/sdk-trace-base@^1.9.0; then
echo "Error: Failed to install dependencies"
exit 1
fi

pnpm run build

PACKED_OTEL_TARBALL=$(npm pack --pack-destination ../../js/artifacts)
echo "packed_otel_tarball=$PACKED_OTEL_TARBALL" >> "$GITHUB_OUTPUT"
- name: Build and pack @braintrust/templates-nunjucks
id: prepare_templates_nunjucks_artifact
shell: bash
run: |
cd integrations/templates-nunjucks
pnpm run build
PACKED_NUNJUCKS_TARBALL=$(npm pack --pack-destination ../../js/artifacts)
echo "packed_nunjucks_tarball=$PACKED_NUNJUCKS_TARBALL" >> "$GITHUB_OUTPUT"
- name: Pack publishable packages
run: node scripts/release/pack-publishable-packages.mjs --output-dir js/artifacts
- name: List artifacts before upload
shell: bash
run: |
echo "Braintrust tarball: ${{ steps.prepare_artifact.outputs.packed_tarball }}"
echo "Browser tarball: ${{ steps.prepare_browser_artifact.outputs.packed_browser_tarball }}"
echo "Otel tarball: ${{ steps.prepare_otel_artifact.outputs.packed_otel_tarball }}"
echo "Templates-nunjucks tarball: ${{ steps.prepare_templates_nunjucks_artifact.outputs.packed_nunjucks_tarball }}"
ls -la js/artifacts/
run: ls -la js/artifacts/
- name: Upload build artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.artifact.outputs.name }}-dist
path: |
js/artifacts/${{ steps.prepare_artifact.outputs.packed_tarball }}
js/artifacts/${{ steps.prepare_browser_artifact.outputs.packed_browser_tarball }}
js/artifacts/${{ steps.prepare_otel_artifact.outputs.packed_otel_tarball }}
js/artifacts/${{ steps.prepare_templates_nunjucks_artifact.outputs.packed_nunjucks_tarball }}
path: js/artifacts/*.tgz
retention-days: 1

e2e-hermetic:
Expand Down Expand Up @@ -238,7 +198,7 @@ jobs:
id: published-version
shell: bash
run: |
PUBLISHED_VERSION=$(npm view braintrust version 2>/dev/null || echo "none")
PUBLISHED_VERSION=$(cd /tmp && npm view braintrust version 2>/dev/null || echo "none")
echo "version=$PUBLISHED_VERSION" >> "$GITHUB_OUTPUT"
echo "Published version: $PUBLISHED_VERSION"
- name: Cache API compatibility test tarball
Expand Down Expand Up @@ -512,6 +472,7 @@ jobs:
- check-typings
- dead-code
- ensure-pinned-actions
- changeset-required
- js-test
- js-build
- e2e-hermetic
Expand Down Expand Up @@ -545,6 +506,7 @@ jobs:
check_result "check-typings" "${{ needs.check-typings.result }}"
check_result "dead-code" "${{ needs.dead-code.result }}"
check_result "ensure-pinned-actions" "${{ needs.ensure-pinned-actions.result }}"
check_result "changeset-required" "${{ needs.changeset-required.result }}"
check_result "js-test" "${{ needs.js-test.result }}"
check_result "js-build" "${{ needs.js-build.result }}"
check_result "e2e-hermetic" "${{ needs.e2e-hermetic.result }}"
Expand Down
56 changes: 27 additions & 29 deletions .github/workflows/publish-js-sdk-canary-scheduler.yaml
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
# This workflow is responsible for scheduling the JavaScript SDK canary publish workflow on a daily basis.
# The actual publish workflow is defined in `publish-js-sdk.yaml`, which is triggered by this scheduler workflow.
# `publish-js-sdk.yaml` has to be where the publish actually happens so that npm trusted publishing still works.
# npm trusted publishing that only one workflow can publish to npm.
name: Publish JS SDK Canary Scheduler

name: Schedule JavaScript SDK Canary Publish
on:
schedule:
- cron: "0 4 * * *" # Nightly at 04:00 UTC
workflow_dispatch:

permissions:
actions: write
contents: read

concurrency:
group: publish-js-sdk-canary-scheduler
cancel-in-progress: false

on:
schedule:
- cron: "17 6 * * *"
workflow_dispatch:

jobs:
dispatch-canary-publish:
dispatch-canary:
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
actions: write
steps:
- name: Dispatch publish workflow
- name: Dispatch canary publish workflow
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { owner, repo } = context.repo;
const ref = context.payload.repository.default_branch;

await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: "publish-js-sdk.yaml",
ref: "main",
owner,
repo,
workflow_id: 'publish-js-sdk.yaml',
ref,
inputs: {
release_type: "canary",
branch: "main",
release_mode: 'canary',
},
});

- name: Summarize dispatch
run: |
{
echo "## JavaScript SDK Canary Dispatch Queued"
echo
echo "- Workflow: \`publish-js-sdk.yaml\`"
echo "- Release type: \`canary\`"
echo "- Branch: \`main\`"
} >> "$GITHUB_STEP_SUMMARY"
core.summary
.addHeading('Dispatched JS canary publish')
.addList([
`Workflow: publish-js-sdk.yaml`,
`Mode: canary`,
`Ref: ${ref}`,
])
.write();
Loading
Loading