Skip to content
Merged
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
116 changes: 116 additions & 0 deletions .github/workflows/apip-api-control-plane-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: API Control Plane Release

on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.1.0)'
required: true
type: string
next_dev_version:
description: 'Next development version (with -SNAPSHOT suffix, e.g. 0.2.0-SNAPSHOT)'
required: true
type: string

env:
DOCKER_REGISTRY: ghcr.io/wso2/api-platform

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
Comment thread
lasanthaS marked this conversation as resolved.

- name: Set version
env:
VERSION: ${{ inputs.version }}
run: |
if [ -z "$(printf '%s' "${VERSION}" | tr -d '[:space:]')" ] || [[ "${VERSION}" == *-SNAPSHOT ]]; then
echo "Error: version must be a non-snapshot release version"
exit 1
fi
make -C portals/api-control-plane version-set "VERSION=${VERSION}"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '24'

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.26.5'
cache: false

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker-container

- name: Install frontend dependencies
working-directory: portals/api-control-plane
run: npm ci

- name: Run tests
run: make test-api-control-plane
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.API_PLATFORM_BOT_TOKEN }}

- name: Build and push multi arch Docker images
run: make build-and-push-api-control-plane-multiarch

- name: Create and push tag
env:
VERSION: ${{ inputs.version }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit -am "Release api-control-plane version ${VERSION}"
git tag -a "apip-api-control-plane/v${VERSION}" -m "API Control Plane ${VERSION}"
git push origin "apip-api-control-plane/v${VERSION}"

- name: Set next dev version
env:
NEXT_DEV_VERSION: ${{ inputs.next_dev_version }}
run: |
if [ -z "${NEXT_DEV_VERSION}" ]; then
echo "Error: next_dev_version input is required"
exit 1
fi
if [[ "${NEXT_DEV_VERSION}" != *-SNAPSHOT ]]; then
echo "Error: next_dev_version must end with -SNAPSHOT (e.g. 0.2.0-SNAPSHOT)"
exit 1
fi
echo "Setting api-control-plane to next dev version: ${NEXT_DEV_VERSION}"
make -C portals/api-control-plane version-set "VERSION=${NEXT_DEV_VERSION}"

- name: Commit version bump
run: |
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
git commit -am "Bump api-control-plane to next dev version"
else
echo "No changes to commit"
fi

- name: Create PR for version bump
id: create-pr
uses: peter-evans/create-pull-request@v6
with:
commit-message: "Bump api-control-plane to next dev version"
title: "chore: Bump api-control-plane to next dev version"
body: |
Automated version bump after release `apip-api-control-plane/v${{ inputs.version }}`

This PR bumps the api-control-plane version to the next development version `${{ inputs.next_dev_version }}`.
branch: api-control-plane-version-bump-${{ github.run_id }}
base: main
delete-branch: true
labels: |
automated
version-bump
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ EVENT_GATEWAY_VERSION := $(shell cat event-gateway/VERSION)
PLATFORM_API_VERSION := $(shell cat platform-api/VERSION)
CLI_VERSION := $(shell cat cli/VERSION)
API_PORTAL_VERSION := $(shell cat portals/api-portal/VERSION)
API_CONTROL_PLANE_VERSION := $(shell cat portals/api-control-plane/VERSION)

# Docker registry configuration
DOCKER_REGISTRY ?= ghcr.io/wso2/api-platform
Expand Down Expand Up @@ -57,6 +58,8 @@ help: ## Show this help message
@echo ' make test-cli - Run CLI tests'
@echo ' make test-api-portal - Run API Portal integration tests'
@echo ' make test-ai-workspace - Run AI Workspace E2E tests'
@echo ' make build-and-push-api-control-plane-multiarch - Build and push API Control Plane image for multiple architectures'
@echo ' make test-api-control-plane - Run API Control Plane tests'
@echo ''
@echo 'Push Targets:'
@echo ' make push-gateway - Push gateway images to registry'
Expand All @@ -75,6 +78,7 @@ version: ## Display current versions
@echo "Platform API Version: $(PLATFORM_API_VERSION)"
@echo "CLI Version: $(CLI_VERSION)"
@echo "API Portal Version: $(API_PORTAL_VERSION)"
@echo "API Control Plane Version: $(API_CONTROL_PLANE_VERSION)"


# Build Targets
Expand Down Expand Up @@ -114,6 +118,12 @@ build-and-push-api-portal-multiarch: ## Build and push API Portal Docker image f
$(MAKE) -C portals/api-portal build-and-push-multiarch
@echo "Successfully built and pushed multi-arch API Portal"

.PHONY: build-and-push-api-control-plane-multiarch
build-and-push-api-control-plane-multiarch: ## Build and push API Control Plane Docker image for multiple architectures (amd64, arm64)
@echo "Building and pushing multi-arch API Control Plane ($(API_CONTROL_PLANE_VERSION))..."
$(MAKE) -C portals/api-control-plane build-and-push-multiarch VERSION=$(API_CONTROL_PLANE_VERSION)
@echo "Successfully built and pushed multi-arch API Control Plane"

# Package Targets
.PHONY: package-event-gateway
package-event-gateway: ## Package event gateway as a self-contained zip (wso2apip-event-gateway-<version>.zip)
Expand Down Expand Up @@ -162,6 +172,11 @@ test-ai-workspace: ## Run AI Workspace E2E tests
@echo "Running AI Workspace E2E tests..."
$(MAKE) -C portals/ai-workspace e2e-ci

.PHONY: test-api-control-plane
test-api-control-plane: ## Run API Control Plane tests
@echo "Running API Control Plane tests..."
$(MAKE) -C portals/api-control-plane test

.PHONY: build-cli
build-cli: ## Build CLI binaries for all platforms
@echo "Building CLI ($(CLI_VERSION))..."
Expand Down
1 change: 1 addition & 0 deletions portals/api-control-plane/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/build/
/coverage/
/node_modules/
/target/
.env*.local
49 changes: 47 additions & 2 deletions portals/api-control-plane/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ SHELL := /bin/bash

VERSION ?= $(shell cat VERSION 2>/dev/null || echo "0.0.0-SNAPSHOT")

.PHONY: help run build bff-build bff-run bff-test bff-tidy
DOCKER_REGISTRY ?= ghcr.io/wso2/api-platform
IMAGE_NAME := $(DOCKER_REGISTRY)/api-control-plane

.PHONY: help run build bff-build bff-run bff-test bff-tidy test build-and-push-multiarch version-set version-bump-patch version-bump-minor version-bump-major version-bump-next-dev version-get-release

# BFF (Backend-for-Frontend) — Go server that serves the SPA, proxies all
# browser->backend traffic, and owns authentication. Local dev runs it over
Expand Down Expand Up @@ -75,5 +78,47 @@ bff-test: ## Run BFF unit tests
bff-tidy: ## Tidy the BFF module
cd $(BFF_DIR) && GOWORK=off go mod tidy

test: ## Run frontend and BFF tests
npm test
$(MAKE) bff-test

build: ## Build the production Docker image
docker build -t api-control-plane:$(VERSION) .
docker build -t $(IMAGE_NAME):$(VERSION) -t api-control-plane:$(VERSION) .

build-and-push-multiarch: ## Build and push multi-architecture Docker image (linux/amd64, linux/arm64)
@echo "Building and pushing multi-arch api-control-plane Docker image: $(IMAGE_NAME):$(VERSION)"
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VERSION=$(VERSION) \
-t $(IMAGE_NAME):$(VERSION) \
--push \
.

version-set: ## Set api-control-plane version
@if [ -z "$(VERSION)" ]; then \
echo "Error: VERSION required"; \
echo "Usage: make version-set VERSION=1.0.0"; \
exit 1; \
fi
@echo "$(VERSION)" > VERSION
@echo "✓ Set api-control-plane version to $(VERSION)"

version-bump-patch: ## Bump patch version
@$(MAKE) version-set VERSION=$$(cd ../.. && bash scripts/next-version.sh patch portals/api-control-plane)

version-bump-minor: ## Bump minor version
@$(MAKE) version-set VERSION=$$(cd ../.. && bash scripts/next-version.sh minor portals/api-control-plane)

version-bump-major: ## Bump major version
@$(MAKE) version-set VERSION=$$(cd ../.. && bash scripts/next-version.sh major portals/api-control-plane)

version-bump-next-dev: ## Bump to next minor dev version with SNAPSHOT suffix
@$(MAKE) version-set VERSION=$$(cd ../.. && bash scripts/next-version.sh next-dev portals/api-control-plane)

version-get-release: ## Get release version (strips SNAPSHOT suffix)
@VERSION=$$(cat VERSION 2>/dev/null | tr -d '[:space:]' | sed 's/-SNAPSHOT//'); \
if [ -z "$$VERSION" ]; then \
echo "Error: VERSION is empty or contains only whitespace. Check portals/api-control-plane/VERSION file." >&2; \
exit 1; \
fi; \
echo "$$VERSION"
14 changes: 11 additions & 3 deletions portals/api-control-plane/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,21 @@ supports two auth modes (`[auth] mode` in `configs/config.toml`):

## Development

Two processes, run side by side:
Three processes, run side by side: Platform API, the BFF, then the portal's
own dev server.

```bash
# Terminal 1 — the BFF, proxying to a running Platform API
# Terminal 1 — Platform API (one-time setup, then run it)
cd <REPO_ROOT>/platform-api
./scripts/setup-local-dev.sh # first time only — generates local certs/keys/admin creds
make run-local # or: make setup-local-dev && make run-local
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Terminal 2 — the BFF, proxying to the running Platform API
cd <REPO_ROOT>/portals/api-control-plane
CONTROL_PLANE_URL=https://localhost:9243 make bff-run

# Terminal 2 — the Vite dev server, proxying same-origin BFF paths to it
# Terminal 3 — the Vite dev server, proxying same-origin BFF paths to it
cd <REPO_ROOT>/portals/api-control-plane
npm install
npm run dev
```
Expand Down
14 changes: 12 additions & 2 deletions portals/api-control-plane/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import { runtimeConfig } from './config/runtime';
import { AuthProvider } from './features/auth/AuthProvider';
import { ProductActivation } from './features/billing/ProductActivation';
import { AppRoutes } from './routes/AppRoutes';
import {
ExtensionsProvider,
type ApiControlPlaneExtension,
} from './extensions';

const isProduction = import.meta.env.PROD;

Expand All @@ -39,7 +43,11 @@ const queryClient = new QueryClient({
},
});

export default function App() {
export type AppProps = {
extensions?: readonly ApiControlPlaneExtension[];
};

export default function App({ extensions = [] }: AppProps) {
return (
<OxygenUIThemeProvider theme={WSO2Theme}>
<ApiClientProvider>
Expand All @@ -49,7 +57,9 @@ export default function App() {
<AuthProvider>
<ProductActivation />
<NotificationProvider>
<AppRoutes />
<ExtensionsProvider extensions={extensions}>
<AppRoutes extensions={extensions} />
</ExtensionsProvider>
</NotificationProvider>
</AuthProvider>
</BrowserRouter>
Expand Down
27 changes: 27 additions & 0 deletions portals/api-control-plane/src/cloud/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Injection seam for cloud-only extensions. `main.tsx` imports
* `cloudExtensions` from here unconditionally, so this file must always
* exist and export a valid (possibly empty) array — this is what lets a
* downstream build overlay just this one file/directory with real cloud
* features, without ever touching App.tsx/main.tsx/extensions.tsx.
*/

import type { ApiControlPlaneExtension } from '../extensions';

export const cloudExtensions: ApiControlPlaneExtension[] = [];
Loading
Loading