diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9dea9c8..181a58f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,9 +8,6 @@ updates: day: "monday" time: "09:00" open-pull-requests-limit: 10 - labels: - - "dependencies" - - "go" commit-message: prefix: "chore(deps)" include: "scope" @@ -23,9 +20,6 @@ updates: day: "monday" time: "09:00" open-pull-requests-limit: 10 - labels: - - "dependencies" - - "github-actions" commit-message: prefix: "chore(deps)" include: "scope" @@ -38,9 +32,6 @@ updates: day: "monday" time: "09:00" open-pull-requests-limit: 5 - labels: - - "dependencies" - - "docker" commit-message: prefix: "chore(deps)" include: "scope" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e83830f..ad6d24e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,9 +17,9 @@ name: "CodeQL Advanced" on: push: - branches: [ "main", "develop" ] + branches: [ "main", "simplify-workflow-to-main-only" ] pull_request: - branches: [ "main", "develop" ] + branches: [ "main" ] schedule: - cron: '30 1 * * 1' # Run every Monday at 1:30 AM UTC @@ -42,10 +42,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@08bc0cf022445eacafaa248bf48da20f26b8fd40 # v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -58,10 +58,8 @@ jobs: echo 'Manual build not required for Go with autobuild' - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@08bc0cf022445eacafaa248bf48da20f26b8fd40 # v4 with: category: "/language:${{ matrix.language }}" output: sarif-results - upload: false # Disabled: conflicts with default setup - # Set to 'true' after disabling GitHub's default CodeQL setup - continue-on-error: true # Don't fail workflow if upload conflicts + upload: true # Enabled to unblock PR merges diff --git a/.github/workflows/create-release-tag.yml b/.github/workflows/create-release-tag.yml new file mode 100644 index 0000000..d45bbc0 --- /dev/null +++ b/.github/workflows/create-release-tag.yml @@ -0,0 +1,154 @@ +name: Create Release Tag + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version (e.g., 1.0.0 or v1.0.0)' + required: true + type: string + prerelease: + description: 'Mark as pre-release' + required: false + type: boolean + default: false + +permissions: + contents: write + +jobs: + create-tag: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Validate and normalize version + id: version + run: | + VERSION="${{ github.event.inputs.version }}" + + # Remove 'v' prefix if present for validation + VERSION_NUMBER="${VERSION#v}" + + # Validate semantic version format + if ! echo "$VERSION_NUMBER" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$'; then + echo "❌ Invalid version format: $VERSION_NUMBER" + echo "Expected format: X.Y.Z or X.Y.Z-prerelease or X.Y.Z+build" + echo "Examples: 1.0.0, 1.0.0-beta.1, 1.0.0+build.123" + exit 1 + fi + + # Always use 'v' prefix for git tag + TAG_NAME="v${VERSION_NUMBER}" + + echo "version=$VERSION_NUMBER" >> $GITHUB_OUTPUT + echo "tag=$TAG_NAME" >> $GITHUB_OUTPUT + echo "✅ Validated version: $TAG_NAME" + + - name: Check if tag already exists + run: | + TAG="${{ steps.version.outputs.tag }}" + + # Check local tags + if git tag -l "$TAG" | grep -q "$TAG"; then + echo "❌ Tag $TAG already exists locally" + exit 1 + fi + + # Check remote tags + git fetch --tags + if git tag -l "$TAG" | grep -q "$TAG"; then + echo "❌ Tag $TAG already exists on remote" + exit 1 + fi + + echo "✅ Tag $TAG is available" + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Get latest commit info + id: commit + run: | + COMMIT_SHA=$(git rev-parse HEAD) + COMMIT_SHORT=$(git rev-parse --short HEAD) + COMMIT_MSG=$(git log -1 --pretty=%B) + + echo "sha=$COMMIT_SHA" >> $GITHUB_OUTPUT + echo "short=$COMMIT_SHORT" >> $GITHUB_OUTPUT + + # Export commit message for tag annotation + { + echo 'message<> $GITHUB_OUTPUT + + - name: Create annotated tag + run: | + TAG="${{ steps.version.outputs.tag }}" + VERSION="${{ steps.version.outputs.version }}" + PRERELEASE="${{ github.event.inputs.prerelease }}" + + # Create tag message + TAG_MESSAGE="Release $TAG + +Automated release created from GitHub Actions workflow. + +Commit: ${{ steps.commit.outputs.short }} +Created: $(date -u +"%Y-%m-%d %H:%M:%S UTC") +Created by: ${{ github.actor }} +Pre-release: $PRERELEASE + +Release Notes: +${{ steps.commit.outputs.message }} + +🤖 Generated with Claude Code +" + + # Create annotated tag + git tag -a "$TAG" -m "$TAG_MESSAGE" + + echo "✅ Created tag: $TAG" + + - name: Push tag to remote + run: | + TAG="${{ steps.version.outputs.tag }}" + + git push origin "$TAG" + + echo "✅ Pushed tag $TAG to remote" + echo "🚀 Release workflow will now be triggered automatically" + + - name: Summary + run: | + TAG="${{ steps.version.outputs.tag }}" + VERSION="${{ steps.version.outputs.version }}" + + echo "## ✅ Release Tag Created Successfully!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Tag**: \`$TAG\`" >> $GITHUB_STEP_SUMMARY + echo "- **Version**: \`$VERSION\`" >> $GITHUB_STEP_SUMMARY + echo "- **Commit**: \`${{ steps.commit.outputs.short }}\`" >> $GITHUB_STEP_SUMMARY + echo "- **Pre-release**: \`${{ github.event.inputs.prerelease }}\`" >> $GITHUB_STEP_SUMMARY + echo "- **Created by**: @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Next Steps:" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "The \`release-package-helm.yml\` workflow has been automatically triggered." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Monitor progress:**" >> $GITHUB_STEP_SUMMARY + echo "- [View Release Workflow](https://github.com/${{ github.repository }}/actions/workflows/release-package-helm.yml)" >> $GITHUB_STEP_SUMMARY + echo "- [View All Actions](https://github.com/${{ github.repository }}/actions)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**After workflow completes:**" >> $GITHUB_STEP_SUMMARY + echo "- [View Releases](https://github.com/${{ github.repository }}/releases)" >> $GITHUB_STEP_SUMMARY + echo "- Docker images will be available at:" >> $GITHUB_STEP_SUMMARY + echo " - \`ghcr.io/${{ github.repository }}:$TAG\`" >> $GITHUB_STEP_SUMMARY + echo " - \`splunk/splunk-ai-operator:$TAG\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/helm-lint-test.yml b/.github/workflows/helm-lint-test.yml index 7ff11b0..37345ca 100644 --- a/.github/workflows/helm-lint-test.yml +++ b/.github/workflows/helm-lint-test.yml @@ -19,22 +19,22 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v4 + uses: azure/setup-helm@bf6a7d304bc2fdb57e0331155b7ebf2c504acf0a # v4 with: version: 'v3.14.0' - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: '3.11' - name: Set up chart-testing - uses: helm/chart-testing-action@v2.6.1 + uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1 - name: Add Helm repositories run: | @@ -139,7 +139,7 @@ jobs: echo "::endgroup::" - name: Create kind cluster for testing - uses: helm/kind-action@v1.10.0 + uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0 with: cluster_name: helm-test wait: 5m diff --git a/.github/workflows/main-build-image.yml b/.github/workflows/main-build-image.yml index 45a1739..b6f17d8 100644 --- a/.github/workflows/main-build-image.yml +++ b/.github/workflows/main-build-image.yml @@ -16,7 +16,7 @@ jobs: IMAGE_NAME: ${{ github.repository }} steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: fetch-depth: 0 @@ -35,7 +35,7 @@ jobs: fi - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 with: go-version: ${{ steps.dotenv.outputs.GO_VERSION }} cache: true @@ -44,7 +44,7 @@ jobs: run: make setup/ginkgo - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 - name: Install Operator SDK run: | @@ -56,17 +56,25 @@ jobs: sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Log in to Docker Hub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Extract metadata (tags, labels) id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + splunk/splunk-ai-operator tags: | type=ref,event=branch type=ref,event=pr @@ -77,7 +85,7 @@ jobs: - name: Build and push image id: build - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . push: true @@ -91,7 +99,7 @@ jobs: # Only run attestation for non-fork PRs and direct pushes # Fork PRs don't have access to id-token which is required for attestations if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request' - uses: actions/attest-build-provenance@v1 + uses: actions/attest-build-provenance@92c65d2898f1f53cfdc910b962cecff86e7f8fcc # v1 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} subject-digest: ${{ steps.build.outputs.digest }} diff --git a/.github/workflows/main-unit-tests.yml b/.github/workflows/main-unit-tests.yml index 26dd4ae..0bda094 100644 --- a/.github/workflows/main-unit-tests.yml +++ b/.github/workflows/main-unit-tests.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - name: Read .env file id: dotenv @@ -24,24 +24,23 @@ jobs: fi - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 with: go-version: ${{ steps.dotenv.outputs.GO_VERSION }} cache: true + - name: Run Unit Tests with Coverage - run: | - go install github.com/mattn/goveralls@latest - make test - #- run: goveralls -coverprofile=coverage.out -service=circle-ci -repotoken ${{ secrets.COVERALLS_TOKEN }} - #- uses: actions/upload-artifact@v4.4.0 - # with: - # name: coverage.out - # path: coverage.out - # - name: Run Unit Tests and E2E Tests with Coverage - # run: go test $(go list ./... | grep -v '/tests') -coverprofile=coverage.out + run: make test + + - name: Upload coverage to Coveralls + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: cover.out + format: golang - - name: Upload coverage file - uses: actions/upload-artifact@v4 + - name: Upload coverage artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: code-coverage - path: coverage.out + path: cover.out diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2eee6eb..4b1fe9d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,11 +1,12 @@ name: Build and Test on: - pull_request: {} + pull_request: + branches: + - main push: branches: - main - - develop permissions: actions: read contents: read diff --git a/.github/workflows/prerelease-update-versions.yml b/.github/workflows/prerelease-update-versions.yml index 290d1b8..88bb1d3 100644 --- a/.github/workflows/prerelease-update-versions.yml +++ b/.github/workflows/prerelease-update-versions.yml @@ -11,7 +11,7 @@ jobs: pull-requests: write steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - name: Deep Fetch run: | @@ -36,26 +36,26 @@ jobs: fi - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 with: go-version: ${{ steps.dotenv.outputs.GO_VERSION }} cache: true - name: Update Helm Version if: github.event.inputs.old_operator_version != github.event.inputs.new_operator_version - uses: jacobtomlinson/gha-find-replace@v3 + uses: jacobtomlinson/gha-find-replace@2ff30f644d2e0078fc028beb9193f5ff0dcad39e # v3 with: find: "${{ github.event.inputs.old_operator_version }}" replace: "${{ github.event.inputs.new_operator_version }}" include: "helm-chart/**.yaml" - name: Update Operator Version in DOCS if: github.event.inputs.old_operator_version != github.event.inputs.new_operator_version - uses: jacobtomlinson/gha-find-replace@v3 + uses: jacobtomlinson/gha-find-replace@2ff30f644d2e0078fc028beb9193f5ff0dcad39e # v3 with: find: "${{ github.event.inputs.old_operator_version }}" replace: "${{ github.event.inputs.new_operator_version }}" include: "**.md" - name: Create Pull Request - uses: peter-evans/create-pull-request@v3.10.1 + uses: peter-evans/create-pull-request@7380612b49221684fefa025244f2ef4008ae50ad # v3.10.1 with: branch: "release/${{ github.event.inputs.new_operator_version }}" title: "Splunk AI Operator ${{ github.event.inputs.new_operator_version }} release" diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml deleted file mode 100644 index 1bb7c5f..0000000 --- a/.github/workflows/prerelease.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Pre-Release Workflow -on: - workflow_dispatch: - inputs: - old_operator_version: - description: 'OLD OPERATOR VERSION' - required: true - new_operator_version: - description: 'NEW OPERATOR VERSION' - required: true - -permissions: - contents: write - pull-requests: write - -jobs: - update-versions: - uses: ./.github/workflows/prerelease-update-versions.yml - with: - old_operator_version: ${{ github.event.inputs.old_operator_version }} - new_operator_version: ${{ github.event.inputs.new_operator_version }} diff --git a/.github/workflows/release-package-helm.yml b/.github/workflows/release-package-helm.yml index 26716b2..40a2459 100644 --- a/.github/workflows/release-package-helm.yml +++ b/.github/workflows/release-package-helm.yml @@ -15,21 +15,121 @@ on: - 'v*.*.*' jobs: + build-and-push-images: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write # Required for artifact attestation + attestations: write # Required for artifact attestation + env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + steps: + - name: Checkout code + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 + with: + fetch-depth: 0 + + - name: Read .env file + id: dotenv + run: | + if [ -f .env ]; then + while IFS='=' read -r key value; do + # Skip comments and empty lines + [[ "$key" =~ ^#.*$ ]] && continue + [[ -z "$key" ]] && continue + # Remove quotes and export + value=$(echo "$value" | sed -e 's/^\"//' -e 's/\"$//' -e "s/^'//" -e "s/'$//") + echo "$key=$value" >> $GITHUB_OUTPUT + done < .env + fi + + - name: Setup Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version: ${{ steps.dotenv.outputs.GO_VERSION }} + cache: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in to Docker Hub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract version from tag + id: version + run: | + # Extract version from tag (remove 'v' prefix) + VERSION=${GITHUB_REF_NAME#v} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Building version: $VERSION" + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5 + with: + images: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + splunk/splunk-ai-operator + tags: | + type=semver,pattern=v{{version}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker images + id: build + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64 + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@92c65d2898f1f53cfdc910b962cecff86e7f8fcc # v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + package: runs-on: ubuntu-latest + needs: build-and-push-images permissions: contents: write + packages: write # For pushing to GHCR OCI registry steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: fetch-depth: 0 - name: Install Helm - uses: azure/setup-helm@v4 + uses: azure/setup-helm@bf6a7d304bc2fdb57e0331155b7ebf2c504acf0a # v4 with: version: 'v3.14.0' + - name: Setup Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 + with: + go-version-file: '.env' + cache: true + - name: Extract version id: version run: | @@ -84,6 +184,27 @@ jobs: echo "✅ Platform chart updated successfully: version=$PLAT_VER, appVersion=$PLAT_APPVER" fi + - name: Generate Kubernetes manifests + run: | + VERSION="${{ steps.version.outputs.version }}" + + # Generate install.yaml with version-specific image tag + echo "Generating Kubernetes manifests for version $VERSION..." + IMG="ghcr.io/splunk/splunk-ai-operator:v$VERSION" make build-installer + + # Rename to version-specific filename + cp dist/install.yaml dist/install-v$VERSION.yaml + + echo "Generated manifests:" + ls -lh dist/install*.yaml + + echo "Verifying image tag in manifest:" + grep "image: ghcr.io/splunk/splunk-ai-operator" dist/install-v$VERSION.yaml || echo "Warning: Image tag not found" + + echo "" + echo "Manifest preview (first 50 lines):" + head -50 dist/install-v$VERSION.yaml + - name: Package Helm charts run: | mkdir -p .helm-releases @@ -108,36 +229,95 @@ jobs: echo "Generated index.yaml:" cat .helm-releases/index.yaml + - name: Log in to GitHub Container Registry + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push Helm charts to OCI registry (GHCR) + run: | + VERSION="${{ steps.version.outputs.version }}" + + # Push operator chart to GHCR OCI registry + if [ -f .helm-releases/splunk-ai-operator-${VERSION}.tgz ]; then + echo "📦 Pushing splunk-ai-operator chart to OCI registry..." + helm push .helm-releases/splunk-ai-operator-${VERSION}.tgz oci://ghcr.io/${{ github.repository_owner }}/charts + echo "✅ Pushed: oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-operator:${VERSION}" + fi + + # Push platform chart to GHCR OCI registry + if [ -f .helm-releases/splunk-ai-platform-${VERSION}.tgz ]; then + echo "📦 Pushing splunk-ai-platform chart to OCI registry..." + helm push .helm-releases/splunk-ai-platform-${VERSION}.tgz oci://ghcr.io/${{ github.repository_owner }}/charts + echo "✅ Pushed: oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-platform:${VERSION}" + fi + + echo "" + echo "📊 Charts published to OCI registry:" + echo " oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-operator:${VERSION}" + echo " oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-platform:${VERSION}" + - name: Create or Update GitHub Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@26994186c0ac3ef5cae75ac16aa32e8153525f77 # v1 with: tag_name: v${{ steps.version.outputs.version }} files: | .helm-releases/*.tgz .helm-releases/index.yaml + dist/install-v${{ steps.version.outputs.version }}.yaml generate_release_notes: true draft: false prerelease: false body: | - ## Splunk AI Operator Helm Charts + ## Splunk AI Operator v${{ steps.version.outputs.version }} - This release includes Helm charts for the Splunk AI Operator. + This release includes Helm charts and Kubernetes manifests for the Splunk AI Operator. - ### Installation + ### Installation Options - #### Direct Install from GitHub Release + #### Option 1: Using Kubernetes Manifests (kubectl) ```bash + kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/install-v${{ steps.version.outputs.version }}.yaml + ``` + + #### Option 2: Using Helm OCI Registry (Recommended) + ```bash + # Requires Helm 3.8+ helm install splunk-ai-operator \ - https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/splunk-ai-operator-${{ steps.version.outputs.version }}.tgz + oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-operator \ + --version ${{ steps.version.outputs.version }} ``` - #### Using as Helm Repository + #### Option 3: Using Helm (Direct from GitHub Release) ```bash - helm repo add splunk-ai https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/ - helm repo update - helm install splunk-ai-operator splunk-ai/splunk-ai-operator --version ${{ steps.version.outputs.version }} + helm install splunk-ai-operator \ + https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/splunk-ai-operator-${{ steps.version.outputs.version }}.tgz ``` - See [Helm Deployment Guide](https://github.com/${{ github.repository }}/blob/main/docs/deployment/helm-deployment.md) for detailed instructions. + ### Release Assets + + **GitHub Release:** + - **install-v${{ steps.version.outputs.version }}.yaml** - Complete Kubernetes manifests (CRDs + Operator) + - **splunk-ai-operator-${{ steps.version.outputs.version }}.tgz** - Operator Helm chart + - **splunk-ai-platform-${{ steps.version.outputs.version }}.tgz** - Platform Helm chart (includes dependencies) + - **index.yaml** - Helm repository index + + **OCI Registry (GHCR):** + - `oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-operator:${{ steps.version.outputs.version }}` + - `oci://ghcr.io/${{ github.repository_owner }}/charts/splunk-ai-platform:${{ steps.version.outputs.version }}` + + ### Container Images + + **Docker Images:** + - `ghcr.io/splunk/splunk-ai-operator:v${{ steps.version.outputs.version }}` + - `splunk/splunk-ai-operator:v${{ steps.version.outputs.version }}` + + ### Documentation + + - [Helm Deployment Guide](https://github.com/${{ github.repository }}/blob/main/docs/helm-deployment.md) + - [Installation Guide](https://github.com/${{ github.repository }}/blob/main/docs/installation.md) + - [API Reference](https://github.com/${{ github.repository }}/blob/main/docs/api-reference.md) env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index cbea6c4..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Pre-Release Workflow -on: - workflow_dispatch: - inputs: - old_operator_version: - description: 'OLD OPERATOR VERSION' - required: true - new_operator_version: - description: 'NEW OPERATOR VERSION' - required: true - -permissions: - contents: write - -jobs: - package-helm: - uses: ./.github/workflows/release-package-helm.yml - with: - old_operator_version: ${{ github.event.inputs.old_operator_version }} - new_operator_version: ${{ github.event.inputs.new_operator_version }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..2400c09 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,59 @@ +name: OpenSSF Scorecard +on: + # For Branch-Protection check. Only the default branch is supported. + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. Run once a week. + schedule: + - cron: '30 1 * * 1' # Weekly on Monday at 1:30 AM UTC + push: + branches: [ "main" ] + workflow_dispatch: + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge + id-token: write + # Needed for Code-Scanning + actions: read + contents: read + + steps: + - name: "Checkout code" + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@v2.4.0 + with: + results_file: results.sarif + results_format: sarif + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results + # For private repositories: + # - `publish_results` will always be set to `false` + publish_results: true + + # Upload the results as artifacts + - name: "Upload artifact" + uses: actions/upload-artifact@v4 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: results.sarif diff --git a/README.md b/README.md index 1dddc49..e4de5cb 100644 --- a/README.md +++ b/README.md @@ -3,113 +3,122 @@ [![Build and Test](https://github.com/splunk/splunk-ai-operator/actions/workflows/main.yml/badge.svg)](https://github.com/splunk/splunk-ai-operator/actions/workflows/main.yml) [![Helm Lint and Test](https://github.com/splunk/splunk-ai-operator/actions/workflows/helm-lint-test.yml/badge.svg)](https://github.com/splunk/splunk-ai-operator/actions/workflows/helm-lint-test.yml) -[![Go Report Card](https://goreportcard.com/badge/github.com/splunk/splunk-ai-operator)](https://goreportcard.com/report/github.com/splunk/splunk-ai-operator) +[![CodeQL](https://github.com/splunk/splunk-ai-operator/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/splunk/splunk-ai-operator/actions/workflows/codeql-analysis.yml) [![Coverage Status](https://coveralls.io/repos/github/splunk/splunk-ai-operator/badge.svg?branch=main)](https://coveralls.io/github/splunk/splunk-ai-operator?branch=main) +[![Go Report Card](https://goreportcard.com/badge/github.com/splunk/splunk-ai-operator)](https://goreportcard.com/report/github.com/splunk/splunk-ai-operator) -[![GitHub release (latest by date)](https://img.shields.io/github/v/release/splunk/splunk-ai-operator)](https://github.com/splunk/splunk-ai-operator/releases) -[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/splunk/splunk-ai-operator?sort=semver)](https://github.com/splunk/splunk-ai-operator/tags) -[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/splunk-ai-operator)](https://artifacthub.io/packages/helm/splunk-ai-operator/splunk-ai-operator) +[![GitHub release](https://img.shields.io/github/v/release/splunk/splunk-ai-operator?include_prereleases)](https://github.com/splunk/splunk-ai-operator/releases) +[![License](https://img.shields.io/github/license/splunk/splunk-ai-operator)](LICENSE) +[![Go Version](https://img.shields.io/github/go-mod/go-version/splunk/splunk-ai-operator)](go.mod) +[![Kubernetes](https://img.shields.io/badge/kubernetes-v1.31+-326CE5.svg?logo=kubernetes&logoColor=white)](https://kubernetes.io/) + -[![Container Image](https://img.shields.io/badge/container-ghcr.io-blue)](https://github.com/splunk/splunk-ai-operator/pkgs/container/splunk-ai-operator) -[![Docker Pulls](https://img.shields.io/docker/pulls/splunk/splunk-ai-operator)](https://hub.docker.com/r/splunk/splunk-ai-operator) - - -[![License](https://img.shields.io/github/license/splunk/splunk-ai-operator)](LICENSE) -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fsplunk%2Fsplunk-ai-operator.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fsplunk%2Fsplunk-ai-operator?ref=badge_shield) +[![GHCR](https://img.shields.io/badge/ghcr.io-splunk%2Fsplunk--ai--operator-blue?logo=github)](https://github.com/splunk/splunk-ai-operator/pkgs/container/splunk-ai-operator) +[![Docker Hub](https://img.shields.io/badge/docker.io-splunk%2Fsplunk--ai--operator-blue?logo=docker&logoColor=white)](https://hub.docker.com/r/splunk/splunk-ai-operator) - + [![GitHub issues](https://img.shields.io/github/issues/splunk/splunk-ai-operator)](https://github.com/splunk/splunk-ai-operator/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/splunk/splunk-ai-operator)](https://github.com/splunk/splunk-ai-operator/pulls) -[![GitHub stars](https://img.shields.io/github/stars/splunk/splunk-ai-operator?style=social)](https://github.com/splunk/splunk-ai-operator/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/splunk/splunk-ai-operator?style=social)](https://github.com/splunk/splunk-ai-operator/network/members) [![GitHub contributors](https://img.shields.io/github/contributors/splunk/splunk-ai-operator)](https://github.com/splunk/splunk-ai-operator/graphs/contributors) - - -[![CodeQL](https://github.com/splunk/splunk-ai-operator/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/splunk/splunk-ai-operator/actions/workflows/codeql-analysis.yml) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/splunk/splunk-ai-operator/badge)](https://api.securityscorecards.dev/projects/github.com/splunk/splunk-ai-operator) - - -[![Documentation](https://img.shields.io/badge/docs-latest-blue)](https://github.com/splunk/splunk-ai-operator/tree/main/docs) -[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/splunk/splunk-ai-operator) - - -[![Go Version](https://img.shields.io/github/go-mod/go-version/splunk/splunk-ai-operator)](go.mod) -[![Kubernetes Version](https://img.shields.io/badge/kubernetes-v1.31+-blue.svg)](https://kubernetes.io/) +[![GitHub stars](https://img.shields.io/github/stars/splunk/splunk-ai-operator)](https://github.com/splunk/splunk-ai-operator/stargazers) --- The Splunk AI Operator is a Kubernetes operator that enables customers to manage AI workloads using standardized CRDs, Helm charts, and Kubernetes primitives without reliance on any specific cloud provider’s tooling or rigid infrastructure. This repo includes the Splunk AI Operator, and multiple CRDs to manage the Splunk AI Platform and Splunk AI Services. ## Getting Started -### Quick Install with Helm (Recommended) +### Quick Install ```bash -# Install the operator from GitHub Release +# Install using Helm OCI registry (Recommended - Helm 3.8+) helm install splunk-ai-operator \ - https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ - -n splunk-ai-operator-system --create-namespace + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace -# Deploy the AI Platform -kubectl apply -f config/samples/ai_v1_aiplatform.yaml +# Or install using kubectl +kubectl apply -f https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/install-v0.1.0.yaml ``` -Images are hosted on GitHub Container Registry (ghcr.io) and Docker Hub. - -See [Helm Deployment Guide](docs/deployment/helm-deployment.md) for detailed installation options. +See [Installation Guide](docs/installation.md) for detailed instructions and all installation methods. ### Prerequisites -- Kubernetes v1.11.3+ cluster -- kubectl v1.11.3+ -- Helm v3.8+ (for Helm installation) -- go v1.23.0+ (for development) -- docker 17.03+ (for development) +- **Kubernetes**: v1.31+ cluster +- **kubectl**: v1.11.3+ +- **Helm**: v3.8+ (for Helm installation) +- **Go**: v1.23.0+ (for development only) +- **Docker**: 17.03+ (for development only) ### Installation Options -**Option 1: Helm (Recommended for Production)** +**Option 1: Helm OCI Registry (Recommended)** ```bash -# Install from GitHub Release +# Requires Helm 3.8+ helm install splunk-ai-operator \ - https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ - -n splunk-ai-operator-system --create-namespace + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace +``` -# Or add Helm repository -helm repo add splunk-ai https://splunk.github.io/splunk-ai-operator/ -helm repo update -helm install splunk-ai-operator splunk-ai/splunk-ai-operator \ - -n splunk-ai-operator-system --create-namespace +**Option 2: kubectl (Manifests)** +```bash +# Install operator with all dependencies +kubectl apply -f https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/install-v0.1.0.yaml ``` -**Option 2: YAML Manifests** +**Option 3: Helm (GitHub Release)** ```bash -kubectl apply -f https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-cluster.yaml +# For compatibility with older Helm versions +helm install splunk-ai-operator \ + https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ + --namespace splunk-ai-operator-system \ + --create-namespace ``` -**Option 3: From Source (Development)** +**Option 4: From Source (Development)** ```bash # Install CRDs make install -# Build and deploy (uses ghcr.io by default) +# Build and deploy make docker-build docker-push IMG=ghcr.io/splunk/splunk-ai-operator:tag make deploy IMG=ghcr.io/splunk/splunk-ai-operator:tag ``` +### Helm Charts + +Charts are published to OCI registry and GitHub Releases: + +- **OCI Registry (GHCR)**: `oci://ghcr.io/splunk/charts/splunk-ai-operator` (recommended) +- **GitHub Releases**: Available as `.tgz` files for compatibility + +```bash +# Install from OCI registry +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 + +# View available versions +# Visit: https://github.com/splunk/splunk-ai-operator/pkgs/container/charts%2Fsplunk-ai-operator +``` + ### Container Images -The operator is published to multiple registries: +Images are published to multiple registries: -- **GitHub Container Registry (GHCR)**: `ghcr.io/splunk/splunk-ai-operator:latest` (recommended) -- **Docker Hub**: `docker.io/splunk/splunk-ai-operator:latest` +- **GHCR**: `ghcr.io/splunk/splunk-ai-operator:v0.1.0` +- **Docker Hub**: `splunk/splunk-ai-operator:v0.1.0` ```bash -# Pull from GHCR +# Pull from GHCR (recommended) docker pull ghcr.io/splunk/splunk-ai-operator:v0.1.0 # Pull from Docker Hub -docker pull docker.io/splunk/splunk-ai-operator:v0.1.0 +docker pull splunk/splunk-ai-operator:v0.1.0 ``` ### Deploy AI Platform diff --git a/docs/deployment/helm-deployment.md b/docs/deployment/helm-deployment.md index c11a231..d6198a0 100644 --- a/docs/deployment/helm-deployment.md +++ b/docs/deployment/helm-deployment.md @@ -1,42 +1,48 @@ # Splunk AI Platform Helm Installation -Helm charts for the Splunk AI Operator are distributed via **GitHub Releases**. This provides versioned, immutable releases with full changelog tracking. +Helm charts for the Splunk AI Operator are distributed via **OCI Registry (GHCR)** and **GitHub Releases**. The OCI registry is the recommended method for Helm 3.8+. ## Installation Methods -### Method 1: Direct Install from GitHub Release (Recommended) +### Method 1: Helm OCI Registry (Recommended) -Install directly from a specific release URL: +Install directly from the OCI registry using Helm 3.8+: ```bash # Latest version: v0.1.0 helm install splunk-ai-operator \ - https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ - -n splunk-ai-operator --create-namespace + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator \ + --create-namespace ``` **Pros:** -- ✅ Simple one-command installation -- ✅ Explicit version control -- ✅ No repository management needed +- ✅ Modern OCI-based distribution +- ✅ No .tgz files in git repository +- ✅ Automatic image verification +- ✅ Native container registry integration -### Method 2: Using as Helm Repository +**Requirements:** +- Helm 3.8+ (for OCI support) +- Internet access to ghcr.io -Add the release as a Helm repository: +### Method 2: Direct Install from GitHub Release -```bash -# Add the Helm repository (using specific version) -helm repo add splunk-ai https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/ -helm repo update +Install directly from a specific release URL (for Helm < 3.8 compatibility): -# Install from repository -helm install splunk-ai-operator splunk-ai/splunk-ai-operator \ - -n splunk-ai-operator --create-namespace +```bash +# Latest version: v0.1.0 +helm install splunk-ai-operator \ + https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ + --namespace splunk-ai-operator \ + --create-namespace ``` **Pros:** -- ✅ Familiar `helm repo` workflow -- ✅ Can use `helm search repo` to find charts +- ✅ Compatible with older Helm versions (3.0+) +- ✅ Simple one-command installation +- ✅ Explicit version control **Available Charts:** * `splunk-ai-operator`: Deploys the Splunk AI Operator (controller for CRDs like `AIPlatform`) @@ -46,7 +52,21 @@ helm install splunk-ai-operator splunk-ai/splunk-ai-operator \ ## Finding Available Versions -View all available releases on GitHub: +### OCI Registry (Recommended) + +View available versions in the GitHub Container Registry: + +**GHCR Package:** https://github.com/splunk/splunk-ai-operator/pkgs/container/charts%2Fsplunk-ai-operator + +```bash +# Show chart information +helm show chart oci://ghcr.io/splunk/charts/splunk-ai-operator --version 0.1.0 + +# List all versions (using crane CLI) +crane ls ghcr.io/splunk/charts/splunk-ai-operator +``` + +### GitHub Releases **Latest Releases:** https://github.com/splunk/splunk-ai-operator/releases @@ -80,24 +100,28 @@ make install To install the controller that manages `AIPlatform` resources: ```bash -# Direct install (recommended) +# OCI Registry (recommended - Helm 3.8+) helm install splunk-ai-operator \ - https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ - -n splunk-ai-operator --create-namespace + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator \ + --create-namespace -# Or using helm repo -helm install splunk-ai-operator splunk-ai/splunk-ai-operator \ - -n splunk-ai-operator --create-namespace +# Or from GitHub Release (for Helm < 3.8) +helm install splunk-ai-operator \ + https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ + --namespace splunk-ai-operator \ + --create-namespace ``` **View available configuration options:** ```bash -# Download and inspect values -curl -sL https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz | tar -xzO splunk-ai-operator/values.yaml +# From OCI registry +helm show values oci://ghcr.io/splunk/charts/splunk-ai-operator --version 0.1.0 -# Or if using helm repo -helm show values splunk-ai/splunk-ai-operator +# Or download and inspect from GitHub Release +curl -sL https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz | tar -xzO splunk-ai-operator/values.yaml ``` --- @@ -152,10 +176,20 @@ weaviateImage: "docker.io/semitechnologies/weaviate:stable-v1.28-007846a" **Install with custom images:** ```bash +# OCI Registry (recommended) +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator \ + --create-namespace \ + --values custom-images.yaml + +# Or from GitHub Release helm install splunk-ai-operator \ https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ - -n splunk-ai-operator --create-namespace \ - -f custom-images.yaml + --namespace splunk-ai-operator \ + --create-namespace \ + --values custom-images.yaml ``` ### Example: Using Docker Hub Only @@ -252,10 +286,20 @@ resources: **Install:** ```bash +# OCI Registry (recommended) +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator \ + --create-namespace \ + --values my-values.yaml + +# Or from GitHub Release helm install splunk-ai-operator \ https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz \ - -n splunk-ai-operator --create-namespace \ - -f my-values.yaml + --namespace splunk-ai-operator \ + --create-namespace \ + --values my-values.yaml ``` --- @@ -292,24 +336,37 @@ splunkConfiguration: ## Install with the Simplified Config ```bash -# Direct install (recommended) +# OCI Registry (recommended - Helm 3.8+) helm install splunk-ai-platform \ - https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-platform-0.1.0.tgz \ - -n ai-stack --create-namespace \ - -f ai-platform-values.yaml + oci://ghcr.io/splunk/charts/splunk-ai-platform \ + --version 0.1.0 \ + --namespace ai-stack \ + --create-namespace \ + --values ai-platform-values.yaml -# Or using helm repo -helm install splunk-ai-platform splunk-ai/splunk-ai-platform \ - -n ai-stack --create-namespace \ - -f ai-platform-values.yaml +# Or from GitHub Release (for Helm < 3.8) +helm install splunk-ai-platform \ + https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-platform-0.1.0.tgz \ + --namespace ai-stack \ + --create-namespace \ + --values ai-platform-values.yaml ``` **Upgrade:** ```bash +# OCI Registry +helm upgrade splunk-ai-platform \ + oci://ghcr.io/splunk/charts/splunk-ai-platform \ + --version 0.1.0 \ + --namespace ai-stack \ + --values ai-platform-values.yaml + +# Or from GitHub Release helm upgrade splunk-ai-platform \ https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-platform-0.1.0.tgz \ - -n ai-stack -f ai-platform-values.yaml + --namespace ai-stack \ + --values ai-platform-values.yaml ``` **Uninstall:** @@ -321,11 +378,11 @@ helm uninstall splunk-ai-platform -n ai-stack **View configurable values:** ```bash -# Download and inspect -curl -sL https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-platform-0.1.0.tgz | tar -xzO splunk-ai-platform/values.yaml +# From OCI registry +helm show values oci://ghcr.io/splunk/charts/splunk-ai-platform --version 0.1.0 -# Or using helm repo -helm show values splunk-ai/splunk-ai-platform +# Or download and inspect from GitHub Release +curl -sL https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-platform-0.1.0.tgz | tar -xzO splunk-ai-platform/values.yaml ``` --- diff --git a/docs/installation.md b/docs/installation.md index 53632c8..9bacbbb 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,102 +1,379 @@ -# Splunk AI Operator Installation Guide +# Installation Guide -## Download Installation YAML for Customization +This guide covers all installation methods for the Splunk AI Operator. -To customize the installation of the **Splunk AI Operator**, start by downloading the installation YAML to your local system and open it in your preferred editor. +## Prerequisites + +- Kubernetes v1.31+ cluster +- kubectl v1.11.3+ +- Helm v3.8+ (for Helm installation) + +## Installation Methods + +### Method 1: Helm OCI Registry (Recommended) + +The recommended way to install using Helm 3.8+: + +```bash +# Install operator +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace +``` + +**With custom values:** +```bash +# Create values file +cat > my-values.yaml </splunk-ai-operator:0.1.0 +If using a private registry for the operator image: + +```bash +# Create image pull secret +kubectl create secret docker-registry private-registry \ + --docker-server=your-registry.com \ + --docker-username=your-username \ + --docker-password=your-password \ + --namespace splunk-ai-operator-system + +# Install with private registry +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 1.0.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace \ + --set image.repository=your-registry.com/splunk-ai-operator \ + --set image.tag=1.0.0 \ + --set imagePullSecrets[0].name=private-registry ``` -Example for related images (e.g., if using AI Platform components like Ray, Weaviate): +### Using Private Registry for Related Images + +Configure private registry for related images (Ray, Weaviate, etc.): -```yaml -env: -- name: RELATED_IMAGE_RAY_OPERATOR - value: /ray-operator:latest -- name: RELATED_IMAGE_WEAVIATE - value: /weaviate:latest +```bash +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 1.0.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace \ + --set env.RELATED_IMAGE_RAY_HEAD=your-registry.com/ray-head:latest \ + --set env.RELATED_IMAGE_WEAVIATE=your-registry.com/weaviate:latest ``` -## Distroless Image Support +--- -Splunk AI Operator supports **distroless images** to improve security by reducing the attack surface. +## Advanced Configuration -### Using the Distroless Image +### Custom Cluster Domain -Use the `-distroless` image tag: +If your cluster uses a custom domain (not `cluster.local`): -```yaml -image: splunk/splunk-ai-operator:0.1.0-distroless +```bash +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 1.0.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace \ + --set env.CLUSTER_DOMAIN=internal.mycluster ``` -### Debugging Distroless Images +### Resource Limits -To debug, add a **sidecar container** with shell utilities: +Configure resource limits: -```yaml -containers: -- name: manager - image: splunk/splunk-ai-operator:0.1.0-distroless -- name: debug-sidecar - image: ubuntu:20.04 - command: ["/bin/bash", "-c", "tail -f /dev/null"] - volumeMounts: - - name: ai-data - mountPath: /data -volumes: -- name: ai-data - emptyDir: {} +```bash +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 1.0.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace \ + --set resources.limits.cpu=1000m \ + --set resources.limits.memory=512Mi \ + --set resources.requests.cpu=100m \ + --set resources.requests.memory=256Mi ``` -Access the sidecar: +### High Availability + +Run multiple replicas for high availability: ```bash -kubectl exec -it -c debug-sidecar -- /bin/bash +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 1.0.0 \ + --namespace splunk-ai-operator-system \ + --create-namespace \ + --set replicaCount=3 \ + --set leaderElection.enabled=true ``` -## Custom Cluster Domain +--- -If your cluster uses a custom domain (not `cluster.local`), set the `CLUSTER_DOMAIN` environment variable in the operator's deployment: +## Verification + +### Check Operator Status + +```bash +# Check operator pods +kubectl get pods -n splunk-ai-operator-system -```yaml -env: -- name: CLUSTER_DOMAIN - value: "internal.mycluster" +# Check operator logs +kubectl logs -n splunk-ai-operator-system \ + -l control-plane=controller-manager \ + --tail=100 + +# Verify CRDs are installed +kubectl get crds | grep ai.splunk.com +``` + +Expected output: ``` +aiplatforms.ai.splunk.com +aiservices.ai.splunk.com +``` + +### Check Webhooks + +```bash +# Verify webhook configuration +kubectl get validatingwebhookconfigurations | grep splunk-ai-operator +kubectl get mutatingwebhookconfigurations | grep splunk-ai-operator + +# Check certificate +kubectl get certificates -n splunk-ai-operator-system +``` + +--- + +## Upgrading + +### Upgrade Operator + +```bash +# Upgrade to new version +helm upgrade splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 1.1.0 \ + --namespace splunk-ai-operator-system +``` + +### View Upgrade Status + +```bash +# Check helm release history +helm history splunk-ai-operator -n splunk-ai-operator-system + +# Check rollout status +kubectl rollout status deployment/splunk-ai-operator-controller-manager \ + -n splunk-ai-operator-system +``` + +--- + +## Uninstallation + +### Using Helm + +```bash +# Uninstall operator +helm uninstall splunk-ai-operator \ + --namespace splunk-ai-operator-system + +# Delete namespace (if desired) +kubectl delete namespace splunk-ai-operator-system + +# Remove CRDs (optional - this will delete all custom resources) +kubectl delete crd aiplatforms.ai.splunk.com +kubectl delete crd aiservices.ai.splunk.com +``` + +### Using kubectl + +```bash +# Delete manifests +kubectl delete -f https://github.com/splunk/splunk-ai-operator/releases/download/v1.0.0/install-v1.0.0.yaml + +# Delete namespace +kubectl delete namespace splunk-ai-operator-system +``` + +--- + +## Troubleshooting + +### Operator Pod Not Starting + +```bash +# Check pod status +kubectl describe pod -n splunk-ai-operator-system \ + -l control-plane=controller-manager + +# Check events +kubectl get events -n splunk-ai-operator-system --sort-by='.lastTimestamp' +``` + +### Webhook Issues + +If webhook is not working: + +```bash +# Check webhook service +kubectl get svc -n splunk-ai-operator-system + +# Check certificate +kubectl get secret -n splunk-ai-operator-system | grep tls + +# Delete and recreate webhook (cert-manager will regenerate) +kubectl delete validatingwebhookconfigurations splunk-ai-operator-validating-webhook +kubectl delete mutatingwebhookconfigurations splunk-ai-operator-mutating-webhook +``` + +### Image Pull Errors + +```bash +# Check image pull secrets +kubectl get secrets -n splunk-ai-operator-system + +# Verify image exists +docker pull ghcr.io/splunk/splunk-ai-operator:v1.0.0 + +# Check pod events for pull errors +kubectl describe pod -n splunk-ai-operator-system +``` + +--- + +## Next Steps + +After installing the operator: + +1. **Deploy AI Platform**: See [Helm Deployment Guide](deployment/helm-deployment.md) +2. **Configure Storage**: See [Storage Configuration](configuration/storage-configuration.md) +3. **Set Up Ingress**: See [Ingress Configuration](configuration/ingress-configuration.md) +4. **Review API**: See [API Reference](api-reference.md) -## Deploy the Splunk AI Platform +--- -After the operator is installed, it can manage the CRDs for the Splunk AI Platform. The Splunk AI Platform CR will create the necessary Splunk AI Service CRs, based on the `features` listed in the manifest. +## Additional Resources -See [Custom Resources Documentation](api-reference.md) for more information on configuring the Splunk AI Platform on your cluster. \ No newline at end of file +- [Helm Deployment Guide](deployment/helm-deployment.md) +- [Local Development](local-development.md) +- [Troubleshooting Guide](troubleshooting.md) +- [Releases](releases.md) diff --git a/docs/releases.md b/docs/releases.md new file mode 100644 index 0000000..06bef96 --- /dev/null +++ b/docs/releases.md @@ -0,0 +1,420 @@ +# Release Guide + +This document describes how to create releases for the Splunk AI Operator. + +## Overview + +Releases are fully automated via GitHub Actions. You create releases from the GitHub UI without needing local git commands. + +## Quick Start + +1. Go to: [Create Release Tag Workflow](https://github.com/splunk/splunk-ai-operator/actions/workflows/create-release-tag.yml) +2. Click **"Run workflow"** +3. Enter version (e.g., `0.1.0` for first release, `0.2.0` for next) +4. Click **"Run workflow"** +5. Wait ~10 minutes - Release created automatically! + +--- + +## Release Process + +### Step 1: Prepare for Release + +**Pre-Release Checklist:** +- [ ] All PRs merged to `main` +- [ ] All CI/CD checks passing +- [ ] CHANGELOG.md updated (if exists) +- [ ] Breaking changes documented (if any) + +### Step 2: Create Release Tag + +1. Navigate to [Create Release Tag](https://github.com/splunk/splunk-ai-operator/actions/workflows/create-release-tag.yml) +2. Click **"Run workflow"** button (top right) +3. Fill in: + - **Use workflow from**: `main` (default) + - **Release version**: `0.1.0` (without 'v' prefix, it's added automatically) + - **Mark as pre-release**: Check for beta/rc releases +4. Click **"Run workflow"** + +### Step 3: Monitor Workflows + +Two workflows run automatically: + +**1. Create Release Tag** (~30 seconds) +- Validates version format +- Creates git tag `v0.1.0` +- Pushes tag to GitHub + +**2. Release Package** (~5-10 minutes) +- Generates Kubernetes manifests +- Packages Helm charts +- Pushes charts to OCI registry (GHCR) +- Builds and pushes Docker images +- Creates GitHub Release with artifacts + +**Monitor at:** +- [All Workflows](https://github.com/splunk/splunk-ai-operator/actions) +- [Release Workflow](https://github.com/splunk/splunk-ai-operator/actions/workflows/release-package-helm.yml) + +### Step 4: Verify Release + +After workflows complete: + +**1. Check GitHub Release:** +``` +https://github.com/splunk/splunk-ai-operator/releases +``` + +Verify assets: +- `install-v0.1.0.yaml` - Kubernetes manifests +- `splunk-ai-operator-0.1.0.tgz` - Helm chart +- `splunk-ai-platform-0.1.0.tgz` - Platform chart +- `index.yaml` - Helm repository index + +**2. Check OCI Registry:** +```bash +# Verify chart is available +helm show chart oci://ghcr.io/splunk/charts/splunk-ai-operator --version 0.1.0 +``` + +**3. Check Docker Images:** +- GHCR: https://github.com/splunk/splunk-ai-operator/pkgs/container/splunk-ai-operator +- Docker Hub: https://hub.docker.com/r/splunk/splunk-ai-operator + +**4. Test Installation:** +```bash +# Test kubectl +kubectl apply -f https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/install-v0.1.0.yaml + +# Test Helm OCI +helm install test-release oci://ghcr.io/splunk/charts/splunk-ai-operator --version 0.1.0 + +# Test Docker +docker pull ghcr.io/splunk/splunk-ai-operator:v0.1.0 +``` + +--- + +## Version Format + +We follow [Semantic Versioning 2.0.0](https://semver.org/): + +### Format: `MAJOR.MINOR.PATCH[-PRERELEASE]` + +**Examples:** +- `0.1.0` - First release +- `0.2.0` - Second release with new features +- `0.1.1` - Patch release +- `1.0.0` - GA release (when ready) +- `0.2.0-beta.1` - Pre-release +- `1.0.0-rc.1` - Release candidate + +### When to Increment + +**MAJOR** (`X.0.0`): +- Breaking API changes +- Incompatible CRD schema changes +- Removal of deprecated features + +**MINOR** (`0.Y.0`): +- New features (backward compatible) +- New CRD fields (with defaults) +- Feature deprecations (with warnings) + +**PATCH** (`0.0.Z`): +- Bug fixes +- Documentation updates +- Security patches (non-breaking) + +**PRERELEASE** (`-suffix`): +- `-alpha.N` - Early testing +- `-beta.N` - Feature complete +- `-rc.N` - Release candidate + +--- + +## What Gets Released + +### Artifacts Published + +When you release `v0.1.0`, the automation creates: + +#### 1. Kubernetes Manifests +``` +install-v0.1.0.yaml +``` +Contains: +- All CRDs (AIPlatform, AIService) +- Operator deployment +- RBAC (ServiceAccount, ClusterRole, etc.) +- Webhooks configuration +- Cert-manager certificates + +#### 2. Helm Charts (OCI Registry) +``` +oci://ghcr.io/splunk/charts/splunk-ai-operator:0.1.0 +oci://ghcr.io/splunk/charts/splunk-ai-platform:0.1.0 +``` + +#### 3. Helm Charts (GitHub Release) +``` +splunk-ai-operator-0.1.0.tgz +splunk-ai-platform-0.1.0.tgz +index.yaml +``` + +#### 4. Docker Images +``` +ghcr.io/splunk/splunk-ai-operator:v0.1.0 +ghcr.io/splunk/splunk-ai-operator:0.1.0 +ghcr.io/splunk/splunk-ai-operator:latest (if on main) + +splunk/splunk-ai-operator:v0.1.0 +splunk/splunk-ai-operator:0.1.0 +splunk/splunk-ai-operator:latest (if on main) +``` + +### Installation Methods + +Users can install via: + +**1. kubectl (Manifests):** +```bash +kubectl apply -f https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/install-v0.1.0.yaml +``` + +**2. Helm OCI (Recommended):** +```bash +helm install splunk-ai-operator \ + oci://ghcr.io/splunk/charts/splunk-ai-operator \ + --version 0.1.0 +``` + +**3. Helm (GitHub Release):** +```bash +helm install splunk-ai-operator \ + https://github.com/splunk/splunk-ai-operator/releases/download/v0.1.0/splunk-ai-operator-0.1.0.tgz +``` + +--- + +## Hotfix Releases + +For critical bug fixes: + +### Process + +1. Merge hotfix PR to `main` +2. Create patch release: `1.0.1` (increment PATCH version) +3. Follow normal release process +4. Communicate to users via GitHub Release notes + +### Example + +If `v0.1.0` has a critical bug: +- Fix merged to `main` +- Create release: `0.1.1` +- Release notes should highlight: + - What was fixed + - Impact of the bug + - Upgrade instructions + +--- + +## Pre-releases + +For testing before GA release: + +### Beta Release + +``` +Version: 0.2.0-beta.1 +Pre-release: ✅ (checked) +``` + +**Use cases:** +- Testing new features +- Getting community feedback +- Validating changes before GA + +### Release Candidate + +``` +Version: 1.0.0-rc.1 +Pre-release: ✅ (checked) +``` + +**Use cases:** +- Final testing before release +- No new features, only bug fixes +- Production-like testing + +--- + +## Troubleshooting + +### Tag Already Exists + +**Error:** +``` +❌ Tag v0.1.0 already exists +``` + +**Solution:** +1. Choose different version, or +2. Delete existing tag (requires admin): + ```bash + git push --delete origin v0.1.0 + ``` +3. Delete GitHub Release if it exists + +### Workflow Failed + +**Check logs:** +1. Go to [Actions](https://github.com/splunk/splunk-ai-operator/actions) +2. Find failed workflow +3. Check error messages + +**Common issues:** +- Docker Hub auth: Check `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN` secrets +- Tests failing: Fix tests on `main` before releasing +- Image build failure: Check Dockerfile and build logs + +### Images Not Appearing + +**Check:** +1. Workflow completed successfully +2. GHCR: May take 5-10 minutes to appear +3. Docker Hub: Check authentication secrets +4. Visibility: Ensure packages are public + +### Charts Not in OCI Registry + +**Verify:** +```bash +# This should work +helm show chart oci://ghcr.io/splunk/charts/splunk-ai-operator --version 0.1.0 +``` + +**If not:** +1. Check workflow logs for OCI push step +2. Verify GHCR authentication +3. Check package visibility settings + +--- + +## Post-Release + +### Required Actions + +After release is published: + +1. **Announcement** + - Update project communication channels + - Post on relevant forums/discussions + +2. **Documentation** + - Update docs if needed + - Add migration guides for breaking changes + +3. **Monitoring** + - Watch for issues + - Monitor downloads/usage + - Respond to user feedback + +### First Release Setup (One-Time) + +For the very first release (`v0.1.0`): + +1. **Make GHCR packages public:** + - Go to: https://github.com/orgs/splunk/packages + - Find: `splunk-ai-operator` and `charts/splunk-ai-operator` + - Settings → Change visibility → Public + +2. **Register on Artifact Hub:** + - Go to: https://artifacthub.io/ + - Sign in with GitHub + - Add repository: `oci://ghcr.io/splunk/charts` + - Charts will be discoverable + +3. **Verify Docker Hub:** + - Check: https://hub.docker.com/r/splunk/splunk-ai-operator + - Images should appear automatically + +--- + +## Security + +### Secrets Required + +Repository secrets needed: +- `DOCKERHUB_USERNAME` - Docker Hub username +- `DOCKERHUB_TOKEN` - Docker Hub access token +- `GITHUB_TOKEN` - Provided automatically by GitHub Actions + +### Supply Chain Security + +Each release includes: +- ✅ SLSA provenance attestation +- ✅ Signed artifacts +- ✅ Vulnerability scanning results +- ✅ SBOM (Software Bill of Materials) + +View security info: +``` +https://github.com/splunk/splunk-ai-operator/security +``` + +--- + +## Best Practices + +### Versioning + +- ✅ Use semantic versioning strictly +- ✅ Document breaking changes clearly +- ✅ Test pre-releases before GA +- ✅ Don't skip versions +- ✅ Tag from `main` branch only + +### Release Notes + +- ✅ Highlight key features/fixes +- ✅ Document breaking changes +- ✅ Include upgrade instructions +- ✅ Link to relevant PRs/issues +- ✅ Thank contributors + +### Testing + +Before releasing: +- ✅ All tests pass on `main` +- ✅ Manual testing completed +- ✅ Documentation updated +- ✅ No known critical bugs + +--- + +## Support + +### Getting Help + +- **Issues:** https://github.com/splunk/splunk-ai-operator/issues +- **Discussions:** https://github.com/splunk/splunk-ai-operator/discussions +- **Documentation:** https://github.com/splunk/splunk-ai-operator/tree/main/docs + +### Release Team + +Contact maintainers for: +- Release access issues +- Secret management +- Emergency hotfixes + +--- + +## Related Documentation + +- [Installation Guide](installation.md) +- [Contributing Guide](../CONTRIBUTING.md) +- [Changelog](../CHANGELOG.md) +- [Security Policy](../SECURITY.md) diff --git a/helm-chart/splunk-ai-operator/artifacthub-repo.yml b/helm-chart/splunk-ai-operator/artifacthub-repo.yml new file mode 100644 index 0000000..e507d4b --- /dev/null +++ b/helm-chart/splunk-ai-operator/artifacthub-repo.yml @@ -0,0 +1,24 @@ +# Artifact Hub repository metadata file +# https://artifacthub.io/docs/topics/repositories/ +repositoryID: splunk-ai-operator +owners: + - name: Splunk AI Team + email: splunkai@cisco.com + +# Optional: Add additional metadata +annotations: + # OpenSSF Scorecard badge + "artifacthub.io/links": | + - name: OpenSSF Scorecard + url: https://securityscorecards.dev/viewer/?uri=github.com/splunk/splunk-ai-operator + # Change log + "artifacthub.io/changes": | + - kind: added + description: Initial release of Splunk AI Operator + # Security updates + "artifacthub.io/containsSecurityUpdates": "false" + # License + "artifacthub.io/license": "Apache-2.0" + # Support and documentation + "artifacthub.io/operator": "true" + "artifacthub.io/operatorCapabilities": "Full Lifecycle" diff --git a/helm-chart/splunk-ai-platform/artifacthub-repo.yml b/helm-chart/splunk-ai-platform/artifacthub-repo.yml new file mode 100644 index 0000000..f75586d --- /dev/null +++ b/helm-chart/splunk-ai-platform/artifacthub-repo.yml @@ -0,0 +1,17 @@ +# Artifact Hub repository metadata file +# https://artifacthub.io/docs/topics/repositories/ +repositoryID: splunk-ai-operator +owners: + - name: Splunk AI Team + email: splunkai@cisco.com + +# Optional: Add additional metadata +annotations: + # OpenSSF Scorecard badge + "artifacthub.io/links": | + - name: OpenSSF Scorecard + url: https://securityscorecards.dev/viewer/?uri=github.com/splunk/splunk-ai-operator + # License + "artifacthub.io/license": "Apache-2.0" + # Dependencies + "artifacthub.io/containsSecurityUpdates": "false"