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
19 changes: 0 additions & 19 deletions .github/workflows/pr-title.yml

This file was deleted.

12 changes: 12 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

# Format only — whether the version is actually newer is decided by release.yml against the
# tags on main. Catching a malformed version here keeps that failure out of the merge.
- name: Validate package.json version format
run: |
set -euo pipefail
VERSION=$(jq -er '.version' package.json)
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::package.json version '$VERSION' is not X.Y.Z — releases are cut from this field"
exit 1
fi
echo "package.json version $VERSION is a releasable X.Y.Z"

- name: Setup Tooling
uses: jdx/mise-action@d6e32c1796099e0f1f3ac741c220a8b7eae9e5dd
with:
Expand Down
27 changes: 26 additions & 1 deletion .github/workflows/publish-as-is.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
repository_dispatch:
types: [publish-package-as-is]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

permissions:
id-token: write
contents: read
Expand All @@ -13,11 +17,32 @@ jobs:
publish:
runs-on: ubuntu-latest
steps:
# repository_dispatch checks out the default branch by default; the payload from release.yml
# pins this to the released commit so the published version matches the release.
- uses: actions/checkout@v4
with:
ref: ${{ github.event.client_payload.ref || github.sha }}
fetch-depth: 0
fetch-tags: true

# npm provenance attests GITHUB_SHA (the default-branch HEAD on repository_dispatch), not
# the checkout ref. Refuse to publish when those differ so we never attest the wrong commit.
# Recovery: re-run this workflow via workflow_dispatch on the release tag.
- name: Refuse mismatched npm provenance
if: github.event_name == 'repository_dispatch'
env:
PAYLOAD_REF: ${{ github.event.client_payload.ref }}
run: |
set -euo pipefail
if [ -z "$PAYLOAD_REF" ]; then
echo "::error::repository_dispatch is missing client_payload.ref"
exit 1
fi
if [ "$GITHUB_SHA" != "$PAYLOAD_REF" ]; then
echo "::error::GITHUB_SHA ($GITHUB_SHA) is default-branch HEAD, but checkout is $PAYLOAD_REF. npm provenance would attest the wrong commit. Re-run publish-as-is.yml via workflow_dispatch on the vX.Y.Z tag."
exit 1
fi

- uses: jdx/mise-action@d6e32c1796099e0f1f3ac741c220a8b7eae9e5dd
with:
install: true
Expand All @@ -32,4 +57,4 @@ jobs:
# set npmjs.com as the registry
npm config set registry https://registry.npmjs.org/
echo "Publishing version as is"
mise run publish
mise run publish
85 changes: 73 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,88 @@ on:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: write
pull-requests: write

jobs:
process:
release:
runs-on: ubuntu-latest
outputs:
releases_created: ${{ steps.release-please.outputs.releases_created }}
prs_created: ${{ steps.release-please.outputs.prs_created }}
released: ${{ steps.release_gate.outputs.should_release }}
steps:
- uses: google-github-actions/release-please-action@v4
id: release-please
# fetch-depth: 0 here, plus `git fetch --tags` in the gate below, so the gate sees every
# release tag — including one created by a prior run that was still queued behind this one.
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: node
skip-github-pull-request: false
fetch-depth: 0

# package.json is the only place the version lives.
- name: Read version from package.json
id: version
run: |
set -euo pipefail
VERSION=$(jq -er '.version' package.json)
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::package.json version '$VERSION' is not X.Y.Z — refusing to release"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Compare version against latest release tag
id: release_gate
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
git fetch --tags origin
# grep -E drops prerelease and suffixed tags that the glob still matches, so only
# X.Y.Z releases take part in the comparison.
LATEST=$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1 || true)
if [ -z "$LATEST" ]; then
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "No prior release tag — v${VERSION} will be the first release"
exit 0
fi
LATEST_VERSION="${LATEST#v}"
if [[ "$VERSION" == "$LATEST_VERSION" ]]; then
echo "::error::v${VERSION} was already released — bump package.json before merging"
exit 1
fi
TAG_FOR_VERSION="v${VERSION}"
LOWEST=$(printf '%s\n%s\n' "$TAG_FOR_VERSION" "$LATEST" | sort -V | head -1)
if [[ "$LOWEST" == "$TAG_FOR_VERSION" ]]; then
echo "::error::package.json version ${VERSION} is older than the latest release ${LATEST} — check for an accidental revert"
exit 1
fi
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "Version ${VERSION} is newer than ${LATEST} — proceeding with release"

# --target creates the tag as part of the release, so a failure can't leave an orphan tag.
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
run: |
gh release create "v${VERSION}" \
--target "$GITHUB_SHA" \
--title "Release v${VERSION}" \
--generate-notes

# Only when the gate passed: a gate failure means the version was already released, and that
# release belongs to an earlier run — deleting it here would destroy a shipped release.
- name: Roll back a partially published release
if: failure() && steps.release_gate.outcome == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
run: gh release delete "v${VERSION}" --yes --cleanup-tag || true

dispatch-publish:
needs: process
needs: release
runs-on: ubuntu-latest
# Only publish once a release is actually cut (release PR merged → tag + GitHub release).
if: needs.process.outputs.releases_created == 'true'
if: needs.release.outputs.released == 'true'
steps:
# Routes to publish-as-is.yml, the workflow npm authorizes for OIDC trusted publishing.
# (publish.yml is not a configured trusted publisher and fails with ENEEDAUTH.)
Expand All @@ -39,3 +97,6 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
event-type: publish-package-as-is
# repository_dispatch always runs the default branch, which may have moved on by then.
# The payload pins the publish to the exact commit that was released.
client-payload: '{"ref": "${{ github.sha }}"}'
22 changes: 0 additions & 22 deletions .mise/tasks/publish
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,6 @@ echo "Publishing to npm"
echo " > with tag: ${usage_tag}..."
echo " > npm version: $(npm --version)"

# For 'next' tag, bump version to a prerelease to avoid conflicts
if [ "${usage_tag}" = "next" ]; then
# Count commits since last tag for a semantic build number
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -n "$LAST_TAG" ]; then
BUILD_NUMBER=$(git rev-list "${LAST_TAG}..HEAD" --count)
echo " > last tag: ${LAST_TAG}"
echo " > commits since last tag: ${BUILD_NUMBER}"
else
BUILD_NUMBER=$(git rev-list HEAD --count)
echo " > no previous tag found"
echo " > total commits: ${BUILD_NUMBER}"
fi
CURRENT_VERSION=$(jq -r '.version' package.json)
PRERELEASE_VERSION="$(semver get release "$CURRENT_VERSION")-next.${BUILD_NUMBER}"
echo " > bumping version: ${CURRENT_VERSION} -> ${PRERELEASE_VERSION}"

if [ "${usage_dry_run}" != "true" ]; then
npm version "${PRERELEASE_VERSION}" --no-git-tag-version --allow-same-version
fi
fi

args=()

if [ -n "${usage_otp}" ]; then
Expand Down
49 changes: 17 additions & 32 deletions .mise/tasks/version
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
#!/usr/bin/env bash
#MISE description="Bump version - handles 'next' prerelease or syncs after 'latest'"
#USAGE flag "-t --tag <tag>" "Tag for versioning strategy (next|latest)" default="next"
#MISE description="Bump the package.json version that releases are cut from"
#USAGE flag "-b --bump <bump>" "Version part to bump (major|minor|patch)" default="patch"

set -e

echo "Bumping version"
echo " > with tag: ${usage_tag}..."
case "${usage_bump}" in
major | minor | patch) ;;
*)
echo "❌ Unknown bump: ${usage_bump}"
echo " Use: --bump patch (default), --bump minor or --bump major"
exit 1
;;
esac

# When bumping "next": prerelease bump only
# When "latest": release-please handles it, but we sync "next" to be ahead
if [ "${usage_tag}" = "next" ]; then
echo "Bumping prerelease version for 'next' tag..."
bun pm version prerelease
echo " > Next version: $(jq -r '.version' package.json)"

elif [ "${usage_tag}" = "latest" ]; then
echo "Syncing 'next' tag to be ahead of 'latest'..."
echo "(Note: 'latest' version should already be bumped by release-please)"

# Get current version (should be latest after release-please)
LATEST_VERSION=$(jq -r '.version' package.json)
echo " > Latest version: $LATEST_VERSION"

# Bump to next prerelease (X.Y.Z -> X.Y.(Z+1)-prerelease.0)
echo " > Bumping 'next' to be ahead of latest..."
bun pm version prerelease

NEXT_VERSION=$(jq -r '.version' package.json)
echo " > Next version: $NEXT_VERSION"

else
echo "❌ Unknown tag: ${usage_tag}"
echo " Use: --tag next (default) or --tag latest"
exit 1
fi
echo "Bumping ${usage_bump} version"

echo "Version bump completed!"
# No git tag: release.yml compares package.json against the tags on main, so a local tag would
# look like an already-shipped release. The tag is created by the GitHub Release.
bun pm version "${usage_bump}" --no-git-tag-version

echo " > New version: $(jq -r '.version' package.json)"
echo "Commit the bump and merge it to main to release it."
4 changes: 0 additions & 4 deletions .release-please-manifest.json

This file was deleted.

18 changes: 8 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,28 @@

## [0.3.0](https://github.com/jfrog/opencode-jfrog-plugin/compare/v0.2.0...v0.3.0) (2026-08-18)


### ⚠ BREAKING CHANGES

* JFROG_URL/JFROG_ACCESS_TOKEN are no longer used for the JFrog Platform MCP; authentication is OAuth via JFROG_PLATFORM_URL.
- JFROG_URL/JFROG_ACCESS_TOKEN are no longer used for the JFrog Platform MCP; authentication is OAuth via JFROG_PLATFORM_URL.

### Features

* JFrog Platform MCP authenticates via OAuth ([#31](https://github.com/jfrog/opencode-jfrog-plugin/issues/31)) ([b2dcdbc](https://github.com/jfrog/opencode-jfrog-plugin/commit/b2dcdbce0ae5960a1cdfb96ce77c0ae67af9846f))
- JFrog Platform MCP authenticates via OAuth ([#31](https://github.com/jfrog/opencode-jfrog-plugin/issues/31)) ([b2dcdbc](https://github.com/jfrog/opencode-jfrog-plugin/commit/b2dcdbce0ae5960a1cdfb96ce77c0ae67af9846f))

## [0.2.0](https://github.com/jfrog/opencode-jfrog-plugin/compare/v0.1.0...v0.2.0) (2026-08-11)


### Features

* **skills:** bump vendored jfrog-skills v0.14.0 -&gt; v0.16.0 ([#22](https://github.com/jfrog/opencode-jfrog-plugin/issues/22)) ([0af4dd9](https://github.com/jfrog/opencode-jfrog-plugin/commit/0af4dd9bb1deb65cc96f14be7962a838246574f5))
* **skills:** sync skills to v0.22.0 ([#25](https://github.com/jfrog/opencode-jfrog-plugin/issues/25)) ([016b99b](https://github.com/jfrog/opencode-jfrog-plugin/commit/016b99bbe0e18f446f57bd4cad3e9f1309ecf40c))
- **skills:** bump vendored jfrog-skills v0.14.0 -&gt; v0.16.0 ([#22](https://github.com/jfrog/opencode-jfrog-plugin/issues/22)) ([0af4dd9](https://github.com/jfrog/opencode-jfrog-plugin/commit/0af4dd9bb1deb65cc96f14be7962a838246574f5))
- **skills:** sync skills to v0.22.0 ([#25](https://github.com/jfrog/opencode-jfrog-plugin/issues/25)) ([016b99b](https://github.com/jfrog/opencode-jfrog-plugin/commit/016b99bbe0e18f446f57bd4cad3e9f1309ecf40c))

## [0.1.0](https://github.com/jfrog/opencode-jfrog-plugin/compare/v0.0.4...v0.1.0) (2026-06-29)


### Features

* **mcp:** JFrog Platform remote MCP (token auth) + install hint ([#19](https://github.com/jfrog/opencode-jfrog-plugin/issues/19)) ([5948dae](https://github.com/jfrog/opencode-jfrog-plugin/commit/5948dae1a2bfabb02afbb07b06d60d1b255a7ecb))
- **mcp:** JFrog Platform remote MCP (token auth) + install hint ([#19](https://github.com/jfrog/opencode-jfrog-plugin/issues/19)) ([5948dae](https://github.com/jfrog/opencode-jfrog-plugin/commit/5948dae1a2bfabb02afbb07b06d60d1b255a7ecb))

## Changelog
---

All notable changes to this project will be documented here by Release Please.
This file is frozen as of v0.3.0. Release notes for later versions are generated per release and
live on the [GitHub Releases](https://github.com/jfrog/opencode-jfrog-plugin/releases) page.
21 changes: 14 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,27 @@ Thank you for your interest in contributing!
mise run test
mise run lint
```
5. Commit using [Conventional Commits](https://www.conventionalcommits.org/) format:
- `feat: add new feature`
- `fix: resolve bug`
- `docs: update readme`
- `chore: update dependencies`
6. Push and open a Pull Request
5. Bump the `version` field in `package.json` — see [Releasing](#releasing)
6. Commit with a descriptive message ([Conventional Commits](https://www.conventionalcommits.org/)
style is welcome, but nothing enforces it)
7. Push and open a Pull Request

## Pull Request Guidelines

- PR titles must follow Conventional Commits format (enforced by CI)
- Keep PRs focused on a single change
- Include tests for new functionality
- Ensure all checks pass before requesting review

## Releasing

Releases are cut from the `version` field in `package.json`: merging a PR that bumps it to a
not-yet-released `X.Y.Z` creates the matching GitHub Release and publishes to npm. See
[RELEASE.md](./RELEASE.md) for the full flow.

Merging to `main` without a version bump fails the Release workflow. That is by design — the
failure reads "already released", and it is how a missing bump gets noticed instead of silently
shipping nothing.

## Code Style

This project uses ESLint and Prettier. Run `mise run lint:fix` to auto-fix issues.
Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,16 @@ Tasks are run with [mise](https://mise.jdx.dev/):

## Release

Releases are automated with [release-please](https://github.com/googleapis/release-please):
merge Conventional-Commit PRs (`feat:`, `fix:`, …) to `main`, and release-please opens a
release PR that bumps the version and updates the changelog. Merging that PR tags the
release and publishes to npm. See [RELEASE.md](RELEASE.md) for details.
Releases are cut automatically by [`.github/workflows/release.yml`](.github/workflows/release.yml)
when a commit lands on `main` with a `package.json` version newer than the latest release tag.
The workflow creates a GitHub Release (and tag), then dispatches npm publishing via
[`publish-as-is.yml`](.github/workflows/publish-as-is.yml) (OIDC trusted publishing).

> Do **not** hand-edit the `version` in `package.json` — release-please manages it.
1. In your PR, bump the `version` field in [`package.json`](package.json).
2. Merge to `main`.

Release notes are generated from merged PRs/commits since the last tag (`gh release create
--generate-notes`). `CHANGELOG.md` is not auto-updated.

---

Expand Down
Loading
Loading