From e686f3b3097a10521c596d4d39367b1a5cc7392b Mon Sep 17 00:00:00 2001 From: Jyothsna Mallavarapu Date: Tue, 1 Sep 2026 14:22:04 -0700 Subject: [PATCH 1/6] ci: add manual workflow to publish npm packages to DrumWave CodeArtifact Mirrors marketplace.monorepo's sdk-publish.yaml OIDC -> codeartifact login -> npm publish pattern (same IAM role, domain, and repository) instead of publish.ts's --provenance flow, which is npmjs.org-only. Manual (workflow_dispatch) rather than tag-triggered, so it never collides with ci.yml's public-npm release flow. Run it after bumping pkg/dbmate/version.go to a version string that doesn't exist upstream (e.g. "2.35.1-drumwave.1"), so the published version is a clean addition in CodeArtifact rather than colliding with (or needing to take precedence over) whatever CodeArtifact's upstream proxy has already cached from the public registry. Note: this assumes reddrummer-github-actions-runner's IAM trust policy already allows this repo's OIDC subject -- that's owned outside this repo and hasn't been confirmed yet. --- .github/workflows/publish-codeartifact.yml | 140 +++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 .github/workflows/publish-codeartifact.yml diff --git a/.github/workflows/publish-codeartifact.yml b/.github/workflows/publish-codeartifact.yml new file mode 100644 index 00000000..75b18046 --- /dev/null +++ b/.github/workflows/publish-codeartifact.yml @@ -0,0 +1,140 @@ +# Publishes this fork's dbmate npm packages to DrumWave's private CodeArtifact +# repository instead of the public npm registry. Mirrors the OIDC -> codeartifact +# login -> npm publish pattern marketplace.monorepo's own sdk-publish.yaml uses +# for @drumwave/mp-internal-sdk / @drumwave/mp-sdk. +# +# Trigger: manual only, via workflow_dispatch. Kept separate from ci.yml's +# `v*` tag trigger so this never collides with (or accidentally piggybacks on) +# the upstream public-npm release flow. Run it after bumping +# pkg/dbmate/version.go to a version string that doesn't exist upstream, e.g. +# "2.35.1-drumwave.1" -- CodeArtifact then just adds it as a new version under +# the existing `dbmate` / `@dbmate/` names, no precedence questions. +name: Publish to CodeArtifact + +on: + workflow_dispatch: {} + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - os: linux + image: ubuntu-latest + arch: 386 + setup: sudo apt-get update && sudo apt-get install -qq gcc-i686-linux-gnu + env: + CC: i686-linux-gnu-gcc + CXX: i686-linux-gnu-g++ + - os: linux + image: ubuntu-latest + arch: amd64 + env: {} + - os: linux + image: ubuntu-latest + arch: arm + setup: sudo apt-get update && sudo apt-get install -qq gcc-arm-linux-gnueabi + env: + CC: arm-linux-gnueabi-gcc + CXX: arm-linux-gnueabi-g++ + GOARM: 6 + - os: linux + image: ubuntu-latest + arch: arm64 + setup: sudo apt-get update && sudo apt-get install -qq gcc-aarch64-linux-gnu + env: + CC: aarch64-linux-gnu-gcc + CXX: aarch64-linux-gnu-g++ + - os: macos + image: macos-latest + arch: amd64 + env: {} + - os: macos + image: macos-latest + arch: arm64 + env: {} + - os: windows + image: windows-latest + arch: amd64 + setup: choco install sqlite + env: {} + name: Build (${{ matrix.os }}/${{ matrix.arch }}) + runs-on: ${{ matrix.image }} + env: ${{ matrix.env }} + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + - name: Setup environment + run: ${{ matrix.setup }} + - run: go mod download + - run: make build ls + env: + GOARCH: ${{ matrix.arch }} + OUTPUT: dbmate-${{ matrix.os }}-${{ matrix.arch }} + - name: Upload build artifacts + uses: actions/upload-artifact@v7 + with: + name: dbmate-${{ matrix.os }}-${{ matrix.arch }} + path: dist/dbmate-* + + publish: + name: Publish npm packages to CodeArtifact + runs-on: ubuntu-latest + needs: build + permissions: + id-token: write # AWS OIDC + contents: read + steps: + - uses: actions/checkout@v7 + + - run: corepack enable + - uses: actions/setup-node@v7 + with: + node-version: 20 + cache: npm + cache-dependency-path: typescript/package-lock.json + + - uses: actions/download-artifact@v8 + with: + path: dist + + - run: npm ci + working-directory: typescript + - run: npm run generate + working-directory: typescript + - run: npm test + working-directory: typescript + + # Same role/domain/repository sdk-publish.yaml uses in marketplace.monorepo. + # Confirm this role's trust policy allows this repo's OIDC subject before + # relying on this workflow -- that's owned by infrastructure.dw-notify, + # not this repo, and isn't something to assume works on the first run. + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6 + with: + role-to-assume: arn:aws:iam::127266044500:role/reddrummer-github-actions-runner + aws-region: us-east-1 + role-session-name: GitHubActions-CodeArtifact-Publish + + - name: Login npm to CodeArtifact + run: | + aws codeartifact login --tool npm \ + --domain drumwave-prod \ + --domain-owner 127266044500 \ + --repository common-library-npm \ + --region us-east-1 + + # publish.ts hardcodes --provenance (npm's OIDC trusted-publish flow, + # npmjs.org-only) and no --registry (implicit npmjs.org default) -- both + # wrong for a private registry, so this loop reimplements its two lines + # of real logic against CodeArtifact instead of calling `npm run publish`. + - name: Publish packages + working-directory: typescript + run: | + for pkg in dist/dbmate dist/@dbmate/*; do + echo "Publishing $pkg" + npm publish "$pkg" + done From bf6c58b05c31ddeed248b70e1e14233edea2034f Mon Sep 17 00:00:00 2001 From: Jyothsna Mallavarapu Date: Tue, 1 Sep 2026 14:38:05 -0700 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20address=20CodeRabbit=20review=20?= =?UTF-8?q?=E2=80=94=20pin=20actions,=20least-privilege=20perms,=20origin-?= =?UTF-8?q?control?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pin all six mutable action refs (checkout x2, setup-go, upload-artifact, setup-node, download-artifact) to reviewed commit SHAs, matching this org's blanket policy (zizmor unpinned-uses) and marketplace.monorepo's own convention. - Add contents: read to the build job (was inheriting default perms) and persist-credentials: false on both checkouts. - Add a put-package-origin-configuration step before publish: CodeArtifact blocks direct publish of any package name it's fetched from its npm upstream by default (dbmate + @dbmate/* are proxied from npmjs.org today), so without this the publish step fails at the registry, not at npm. Flagged by CodeRabbit as the one Heavy-lift finding — genuinely would have blocked the first real run. --- .github/workflows/publish-codeartifact.yml | 42 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-codeartifact.yml b/.github/workflows/publish-codeartifact.yml index 75b18046..867e1c5e 100644 --- a/.github/workflows/publish-codeartifact.yml +++ b/.github/workflows/publish-codeartifact.yml @@ -16,6 +16,8 @@ on: jobs: build: + permissions: + contents: read strategy: fail-fast: false matrix: @@ -63,8 +65,10 @@ jobs: runs-on: ${{ matrix.image }} env: ${{ matrix.env }} steps: - - uses: actions/checkout@v7 - - uses: actions/setup-go@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version-file: go.mod - name: Setup environment @@ -75,7 +79,7 @@ jobs: GOARCH: ${{ matrix.arch }} OUTPUT: dbmate-${{ matrix.os }}-${{ matrix.arch }} - name: Upload build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: dbmate-${{ matrix.os }}-${{ matrix.arch }} path: dist/dbmate-* @@ -88,16 +92,18 @@ jobs: id-token: write # AWS OIDC contents: read steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false - run: corepack enable - - uses: actions/setup-node@v7 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 with: node-version: 20 cache: npm cache-dependency-path: typescript/package-lock.json - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: path: dist @@ -127,6 +133,30 @@ jobs: --repository common-library-npm \ --region us-east-1 + # CodeArtifact's origin-control feature blocks direct publish of any + # package name the repository has ever fetched from its npm upstream, + # by default (anti dependency-confusion protection) -- dbmate and + # @dbmate/ are proxied from npmjs.org today (see + # marketplace.monorepo's package-lock.json), so without this the + # publish step below fails with a CodeArtifact-side rejection, not an + # npm error. Requires codeartifact:PutPackageOriginConfiguration on the + # assumed role -- reddrummer-github-actions-runner may not have it yet; + # if this step fails with AccessDenied, an admin needs to grant it or + # run the equivalent command by hand once. + - name: Allow direct publish for dbmate packages in CodeArtifact + working-directory: typescript + run: | + for pkg_dir in dist/dbmate dist/@dbmate/*; do + name=$(node -p "require('./$pkg_dir/package.json').name") + aws codeartifact put-package-origin-configuration \ + --domain drumwave-prod \ + --domain-owner 127266044500 \ + --repository common-library-npm \ + --format npm \ + --package "$name" \ + --restrictions publish=ALLOW,upstream=ALLOW + done + # publish.ts hardcodes --provenance (npm's OIDC trusted-publish flow, # npmjs.org-only) and no --registry (implicit npmjs.org default) -- both # wrong for a private registry, so this loop reimplements its two lines From d8662c34b3c5071beb5c35ab1e6336a89e2cd078 Mon Sep 17 00:00:00 2001 From: Jyothsna Mallavarapu Date: Tue, 1 Sep 2026 14:47:20 -0700 Subject: [PATCH 3/6] fix: bump golang.org/x/crypto to v0.55.0, fixing CVE-2026-56854 golang.org/x/crypto v0.52.0 (an indirect dependency, pulled in via the Google Cloud SDK deps for BigQuery support) is vulnerable to an SSH auth-callback source-address-restriction bypass, fixed upstream in v0.55.0. Confirmed via the built binary's embedded module info that this bump actually takes effect (unlike bumping dbmate's own npm version alone, which doesn't move this indirect dependency at all -- verified separately as a dead end). `go get golang.org/x/crypto@v0.55.0 && go mod tidy` pulled a few other golang.org/x/* transitive bumps along for MVS consistency; nothing in dbmate's own code changed. `go build ./...` and `go vet ./...` are clean, and the built binary now embeds golang.org/x/crypto@v0.55.0 (confirmed via strings on the binary), not v0.52.0. Also bumps the npm package version to 2.35.1-drumwave.1 so this ships as a clean addition in DrumWave's CodeArtifact mirror rather than colliding with (or needing to take precedence over) the real upstream 2.35.1 it already proxies. --- go.mod | 16 ++++++++-------- go.sum | 32 ++++++++++++++++---------------- pkg/dbmate/version.go | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index ed7904d9..a94eeb9e 100644 --- a/go.mod +++ b/go.mod @@ -62,17 +62,17 @@ require ( go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.52.0 // indirect + golang.org/x/crypto v0.55.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/mod v0.38.0 // indirect + golang.org/x/net v0.57.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/telemetry v0.0.0-20260428171046-76f71b9afea0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/sync v0.22.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 // indirect + golang.org/x/text v0.41.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.44.0 // indirect + golang.org/x/tools v0.48.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20260427160629-7cedc36a6bc4 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260427160629-7cedc36a6bc4 // indirect diff --git a/go.sum b/go.sum index 8fc01d1f..c2a89a3b 100644 --- a/go.sum +++ b/go.sum @@ -490,8 +490,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -530,8 +530,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -579,8 +579,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= +golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -622,8 +622,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -688,10 +688,10 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260428171046-76f71b9afea0 h1:ER5jHKKGuNOscKUx6ChPob4dxC3gP5lkzWXa0JPJWRQ= -golang.org/x/telemetry v0.0.0-20260428171046-76f71b9afea0/go.mod h1:kHjTxDEnAu6/Nl9lDkzjWpR+bmKfxeiRuSDlsMb70gE= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 h1:RJhm5l6Fo4rmEIcndxDllNhhf/fAx8qIm4t6A7vpm2A= +golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959/go.mod h1:LV7u5Oco+Z/g6XI7PqN+EUUUGGkEcmB1uj2ceI0fOVg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -704,8 +704,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -763,8 +763,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= -golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/dbmate/version.go b/pkg/dbmate/version.go index 02f4a6b3..8ceb9a9f 100644 --- a/pkg/dbmate/version.go +++ b/pkg/dbmate/version.go @@ -1,4 +1,4 @@ package dbmate // Version of dbmate -const Version = "2.35.1" +const Version = "2.35.1-drumwave.1" From 42ca47b6b56a266dd4f7cebf98648d84d01afee3 Mon Sep 17 00:00:00 2001 From: Jyothsna Mallavarapu Date: Wed, 2 Sep 2026 10:36:02 -0700 Subject: [PATCH 4/6] fix(codeartifact): publish under @drumwave scope instead of upstream names Addresses afrolov-dw's review: publishing dbmate/@dbmate/ with CodeArtifact's origin publish=ALLOW,upstream=ALLOW permanently weakens dependency-confusion protection on the shared common-library-npm repo, and a future real dbmate release would silently win precedence over this patched prerelease build with no green-lockfile signal to catch it. Renaming to @drumwave/dbmate + @drumwave/dbmate- removes both risks: those names were never fetched from npmjs.org, so origin-control never blocks them. The put-package-origin-configuration step -- along with CodeRabbit's still-open --namespace/--package finding on it -- is now unnecessary and removed entirely. Verified end-to-end locally: `npm run generate` produces the renamed packages, resolveBinary() resolves through node_modules/@drumwave, and the real darwin-arm64 Go binary runs correctly through the full CLI path. --- .github/workflows/publish-codeartifact.yml | 49 +++++++------------ typescript/generate.ts | 12 ++--- typescript/package.json | 2 +- typescript/packages/dbmate/package.json | 2 +- .../packages/dbmate/src/resolveBinary.ts | 2 +- 5 files changed, 28 insertions(+), 39 deletions(-) diff --git a/.github/workflows/publish-codeartifact.yml b/.github/workflows/publish-codeartifact.yml index 867e1c5e..99ea810d 100644 --- a/.github/workflows/publish-codeartifact.yml +++ b/.github/workflows/publish-codeartifact.yml @@ -3,12 +3,21 @@ # login -> npm publish pattern marketplace.monorepo's own sdk-publish.yaml uses # for @drumwave/mp-internal-sdk / @drumwave/mp-sdk. # +# Published under the @drumwave scope (@drumwave/dbmate, @drumwave/dbmate-) +# rather than the upstream public names (dbmate, @dbmate/). Publishing +# under the same names CodeArtifact already proxies from npmjs.org would mean +# permanently relaxing origin-control on common-library-npm -- a repo shared with +# every other internal package -- and with upstream still reachable, a real dbmate +# release could silently take precedence over this patched build later (prerelease +# versions don't win an ordinary semver range against it). Scoping to @drumwave +# sidesteps both: the name was never fetched from upstream, so no origin-control +# change is needed at all. +# # Trigger: manual only, via workflow_dispatch. Kept separate from ci.yml's # `v*` tag trigger so this never collides with (or accidentally piggybacks on) # the upstream public-npm release flow. Run it after bumping # pkg/dbmate/version.go to a version string that doesn't exist upstream, e.g. -# "2.35.1-drumwave.1" -- CodeArtifact then just adds it as a new version under -# the existing `dbmate` / `@dbmate/` names, no precedence questions. +# "2.35.1-drumwave.1". name: Publish to CodeArtifact on: @@ -115,9 +124,9 @@ jobs: working-directory: typescript # Same role/domain/repository sdk-publish.yaml uses in marketplace.monorepo. - # Confirm this role's trust policy allows this repo's OIDC subject before - # relying on this workflow -- that's owned by infrastructure.dw-notify, - # not this repo, and isn't something to assume works on the first run. + # Confirmed with the SRE team directly: the role's trust policy already + # accepts any reddrummer/* repo (org-wide wildcard subject) and it has + # AWSCodeArtifactAdminAccess attached, so no IAM changes were needed here. - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6 with: @@ -133,38 +142,18 @@ jobs: --repository common-library-npm \ --region us-east-1 - # CodeArtifact's origin-control feature blocks direct publish of any - # package name the repository has ever fetched from its npm upstream, - # by default (anti dependency-confusion protection) -- dbmate and - # @dbmate/ are proxied from npmjs.org today (see - # marketplace.monorepo's package-lock.json), so without this the - # publish step below fails with a CodeArtifact-side rejection, not an - # npm error. Requires codeartifact:PutPackageOriginConfiguration on the - # assumed role -- reddrummer-github-actions-runner may not have it yet; - # if this step fails with AccessDenied, an admin needs to grant it or - # run the equivalent command by hand once. - - name: Allow direct publish for dbmate packages in CodeArtifact - working-directory: typescript - run: | - for pkg_dir in dist/dbmate dist/@dbmate/*; do - name=$(node -p "require('./$pkg_dir/package.json').name") - aws codeartifact put-package-origin-configuration \ - --domain drumwave-prod \ - --domain-owner 127266044500 \ - --repository common-library-npm \ - --format npm \ - --package "$name" \ - --restrictions publish=ALLOW,upstream=ALLOW - done - # publish.ts hardcodes --provenance (npm's OIDC trusted-publish flow, # npmjs.org-only) and no --registry (implicit npmjs.org default) -- both # wrong for a private registry, so this loop reimplements its two lines # of real logic against CodeArtifact instead of calling `npm run publish`. + # + # No CodeArtifact origin-control step is needed here: these publish as + # @drumwave/dbmate and @drumwave/dbmate-, names never fetched + # from npmjs.org, so origin-control never blocks them. - name: Publish packages working-directory: typescript run: | - for pkg in dist/dbmate dist/@dbmate/*; do + for pkg in dist/@drumwave/dbmate dist/@drumwave/dbmate-*; do echo "Publishing $pkg" npm publish "$pkg" done diff --git a/typescript/generate.ts b/typescript/generate.ts index 26b639e9..1de1917d 100644 --- a/typescript/generate.ts +++ b/typescript/generate.ts @@ -100,8 +100,8 @@ async function main() { throw new Error(`Unknown arch ${build.arch}`); } - const name = `@dbmate/${jsOS}-${jsArch}`; - const targetDir = `dist/@dbmate/${jsOS}-${jsArch}`; + const name = `@drumwave/dbmate-${jsOS}-${jsArch}`; + const targetDir = `dist/@drumwave/dbmate-${jsOS}-${jsArch}`; const binext = jsOS === "win32" ? ".exe" : ""; const templateVars = { jsOS, jsArch, name, version }; @@ -137,19 +137,19 @@ async function main() { } // copy main package - await cp("packages/dbmate", "dist/dbmate", { + await cp("packages/dbmate", "dist/@drumwave/dbmate", { recursive: true, }); // write package.json await writeFile( - "dist/dbmate/package.json", + "dist/@drumwave/dbmate/package.json", JSON.stringify(mainPackageJson, undefined, 2), ); // copy readme and license - await cp("../LICENSE", "dist/dbmate/LICENSE"); - await cp("../README.md", "dist/dbmate/README.md"); + await cp("../LICENSE", "dist/@drumwave/dbmate/LICENSE"); + await cp("../README.md", "dist/@drumwave/dbmate/README.md"); } main().catch((e: unknown) => { diff --git a/typescript/package.json b/typescript/package.json index 2f8444f1..aca48194 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -6,7 +6,7 @@ "clean": "rimraf dist packages/dbmate/dist", "lint": "eslint --report-unused-disable-directives --fix .", "lint:ci": "eslint --report-unused-disable-directives .", - "test": "mkdir -p dist/dbmate/node_modules && ln -sfn ../../@dbmate dist/dbmate/node_modules/@dbmate && node --input-type=module -e \"const { resolveBinary } = await import('./dist/dbmate/dist/index.js'); const bin = resolveBinary(); console.log('resolved binary:', bin);\"", + "test": "mkdir -p dist/@drumwave/dbmate/node_modules && ln -sfn ../.. dist/@drumwave/dbmate/node_modules/@drumwave && node --input-type=module -e \"const { resolveBinary } = await import('./dist/@drumwave/dbmate/dist/index.js'); const bin = resolveBinary(); console.log('resolved binary:', bin);\"", "generate": "tsx generate.ts", "publish": "tsx publish.ts" }, diff --git a/typescript/packages/dbmate/package.json b/typescript/packages/dbmate/package.json index 47575489..f7162a23 100644 --- a/typescript/packages/dbmate/package.json +++ b/typescript/packages/dbmate/package.json @@ -1,5 +1,5 @@ { - "name": "dbmate", + "name": "@drumwave/dbmate", "version": "", "description": "A lightweight, framework-agnostic database migration tool", "repository": { diff --git a/typescript/packages/dbmate/src/resolveBinary.ts b/typescript/packages/dbmate/src/resolveBinary.ts index 9b92eb6a..d4eff97b 100644 --- a/typescript/packages/dbmate/src/resolveBinary.ts +++ b/typescript/packages/dbmate/src/resolveBinary.ts @@ -8,7 +8,7 @@ const require = createRequire(import.meta.url); * */ export function resolveBinary(): string { const ext = platform === "win32" ? ".exe" : ""; - const path = `@dbmate/${platform}-${arch}/bin/dbmate${ext}`; + const path = `@drumwave/dbmate-${platform}-${arch}/bin/dbmate${ext}`; try { return require.resolve(path); From d63e9fc15c9831d9170f57571d305077489bbc2a Mon Sep 17 00:00:00 2001 From: Jyothsna Mallavarapu Date: Wed, 2 Sep 2026 10:46:15 -0700 Subject: [PATCH 5/6] docs(codeartifact): document accepted shared-role privilege tradeoff CodeRabbit flagged (correctly) that reddrummer-github-actions-runner is org-wide-trusted with AWSCodeArtifactAdminAccess, so any reddrummer/* repo's CI can already modify anything in common-library-npm. The literal suggested fix -- restrict this role's OIDC subject to reddrummer/dbmate -- would break marketplace.monorepo's sdk-publish.yaml, which depends on this same shared role. Confirmed with SRE this is accepted as-is for now; documenting the tradeoff and the properly-scoped follow-up (a dedicated dbmate OIDC role, matching offers-service/pricing-service/dw-notify's per-repo pattern) inline so it isn't silently forgotten. --- .github/workflows/publish-codeartifact.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/publish-codeartifact.yml b/.github/workflows/publish-codeartifact.yml index 99ea810d..bbcbad33 100644 --- a/.github/workflows/publish-codeartifact.yml +++ b/.github/workflows/publish-codeartifact.yml @@ -127,6 +127,16 @@ jobs: # Confirmed with the SRE team directly: the role's trust policy already # accepts any reddrummer/* repo (org-wide wildcard subject) and it has # AWSCodeArtifactAdminAccess attached, so no IAM changes were needed here. + # + # Known tradeoff, accepted for now (see PR #1 review): this is a shared, + # org-wide-trusted role with admin-level CodeArtifact access, so any + # reddrummer/* repo's CI can already modify anything in common-library-npm, + # not just this repo's packages. marketplace.monorepo's sdk-publish.yaml + # depends on this same shared role, so narrowing its trust to just + # reddrummer/dbmate isn't an option here -- a properly-scoped fix would + # mean giving dbmate its own dedicated OIDC role instead (the per-repo + # actions-role pattern offers-service/pricing-service/dw-notify already + # use), which is a separate Terraform PR against sre.infrastructure. - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6 with: From 8a8fd5597ad3cbd947c657f67963ac2947bf33bc Mon Sep 17 00:00:00 2001 From: Jyothsna Mallavarapu Date: Wed, 2 Sep 2026 11:00:06 -0700 Subject: [PATCH 6/6] fix(ci): disable upstream's tag-triggered public npm publish step CodeRabbit caught a real regression: generate.ts now writes dist/@drumwave/dbmate(-), but publish.ts (used by this job's tag-triggered `npm run publish` step) still hardcodes the old dist/dbmate / dist/@dbmate paths. A pushed v* tag would crash at readdir("dist/@dbmate"). Rather than patch publish.ts to the new layout, disable the step entirely -- this fork should never auto-publish to public npmjs.org under any name (neither the original dbmate/@dbmate identity, which isn't ours to release under, nor the new @drumwave scope, which has no business on the public registry). Internal releases go through publish-codeartifact.yml instead. Also drops the job's now-unused id-token: write permission (was only there for npm's OIDC provenance publish). --- .github/workflows/ci.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23dbd66d..207af60d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -186,7 +186,6 @@ jobs: needs: build permissions: contents: read - id-token: write steps: - uses: actions/checkout@v7 @@ -217,6 +216,11 @@ jobs: - run: npm test working-directory: typescript - - run: npm run publish - if: ${{ startsWith(github.ref, 'refs/tags/v') }} - working-directory: typescript + # Deliberately not running `npm run publish` here (upstream's tag-triggered + # public npm release step). This fork never publishes to public npmjs.org + # under any name -- internal releases go through publish-codeartifact.yml + # instead, to DrumWave's private CodeArtifact registry. Left disabled rather + # than adapted to publish.ts's dist/dbmate layout: `generate.ts` now writes + # dist/@drumwave/dbmate(-), so publish.ts's hardcoded dist/dbmate + # / dist/@dbmate paths no longer exist, and readdir("dist/@dbmate") would + # throw if this step ever ran (e.g. a stray `v*` tag pushed by accident).