From 1b9b592406e804d88e74a3898b452a5d14f53954 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 16 Dec 2025 12:02:32 +0530 Subject: [PATCH 1/3] fix(INF2-ecloud-infra-security): add codeowners to workflows protection --- .github/CODEOWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..888e774 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +# CODEOWNERS - Workflow Protection +# Protect all workflows +/.github/workflows/ @Layr-Labs/security +/.github/CODEOWNERS @Layr-Labs/security \ No newline at end of file From 57397f5c5b4683a591ef80f38ad0b6e463a24ea3 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 16 Dec 2025 12:10:48 +0530 Subject: [PATCH 2/3] fix(INF2-ecloud-infra-security): add individuals to owners --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 888e774..c6a0d18 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # CODEOWNERS - Workflow Protection # Protect all workflows -/.github/workflows/ @Layr-Labs/security -/.github/CODEOWNERS @Layr-Labs/security \ No newline at end of file +/.github/workflows/ @anupsv @vineetguptadev +/.github/CODEOWNERS @anupsv @vineetguptadev \ No newline at end of file From 460585341acb16bb13b210a5170d0db0768d65a6 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 6 Jan 2026 19:05:07 +0000 Subject: [PATCH 3/3] fix(INF2-ecloud-pipeline): added single pipeline --- .github/workflows/release-dev.yml | 135 ----------- .github/workflows/release-prod.yml | 176 -------------- .github/workflows/release.yml | 358 +++++++++++++++++++++++++++++ Makefile | 227 ++++++++++++++++++ README.md | 169 +++++++++++++- 5 files changed, 749 insertions(+), 316 deletions(-) delete mode 100644 .github/workflows/release-dev.yml delete mode 100644 .github/workflows/release-prod.yml create mode 100644 .github/workflows/release.yml create mode 100644 Makefile diff --git a/.github/workflows/release-dev.yml b/.github/workflows/release-dev.yml deleted file mode 100644 index a69be65..0000000 --- a/.github/workflows/release-dev.yml +++ /dev/null @@ -1,135 +0,0 @@ -name: Release Dev - -on: - push: - tags: - - "v*-dev*" - -permissions: - contents: write - id-token: write - -env: - NODE_VERSION: "20.x" - -jobs: - build-and-publish: - runs-on: ubuntu-latest - steps: - - name: Enforce dev tag format - run: | - VERSION="${{ github.ref_name }}" - - if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-dev ]]; then - echo "Version '$VERSION' does not match required pattern v..-dev*" - exit 1 - fi - - echo "VERSION=$VERSION" >> $GITHUB_ENV - - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - fetch-depth: 0 - - - name: Set version from tag - run: | - # Clean leading v from provided version - PACKAGE_VERSION="${VERSION#v}" - echo "VERSION=$VERSION" >> $GITHUB_ENV - echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV - echo "Building dev version: $PACKAGE_VERSION" - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - registry-url: "https://registry.npmjs.org" - cache: "pnpm" - - - name: Install dependencies - working-directory: . - run: pnpm install --frozen-lockfile - - - name: Build SDK (dev) - dependency for CLI - working-directory: ./packages/sdk - env: - BUILD_TYPE: dev - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - POSTHOG_API_KEY_BUILD_TIME: ${{ secrets.POSTHOG_API_KEY }} - run: | - pnpm run build - - - name: Build CLI (dev) - working-directory: ./packages/cli - env: - BUILD_TYPE: dev - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - POSTHOG_API_KEY_BUILD_TIME: ${{ secrets.POSTHOG_API_KEY }} - run: | - pnpm run build - - - name: Get short sha - run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV - env: - GITHUB_SHA: ${{ github.sha }} - - - name: Generate SDK VERSION file - working-directory: ./packages/sdk - env: - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - GITHUB_SHA: ${{ env.SHORT_SHA }} - run: | - node scripts/generate-version.js - - - name: Generate CLI VERSION file - working-directory: ./packages/cli - env: - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - GITHUB_SHA: ${{ env.SHORT_SHA }} - run: | - node scripts/generate-version.js - - - name: Update SDK package.json for publishing - working-directory: ./packages/sdk - run: | - # Update version (keep default package name) - npm pkg set version="${{ env.PACKAGE_VERSION }}" - - - name: Publish SDK to npm (dev) - working-directory: ./packages/sdk - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - npm publish --tag dev --access public - - - name: Update CLI package.json for dev namespace - working-directory: ./packages/cli - run: | - # Update version to tag as dev - npm pkg set version="${{ env.PACKAGE_VERSION }}" - # Update SDK dependency to match published version - npm pkg set "dependencies.@layr-labs/ecloud-sdk"="${{ env.PACKAGE_VERSION }}" - # Verify changes - cat package.json | grep -A 2 '"name"' - cat package.json | grep -A 1 '"@layr-labs/ecloud-sdk"' - - - name: Publish CLI to npm (dev) - working-directory: ./packages/cli - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - npm publish --tag dev --access public - - - name: Summary - run: | - echo "✅ Dev release published successfully!" - echo "📦 SDK Package: @layr-labs/ecloud-sdk@${{ env.PACKAGE_VERSION }} (tag: dev)" - echo "📦 CLI Package: @layr-labs/ecloud-cli@${{ env.PACKAGE_VERSION }} (tag: dev)" - echo "🏷️ Tag: dev" - echo "🔗 Install with: npm install -g @layr-labs/ecloud-cli@dev" diff --git a/.github/workflows/release-prod.yml b/.github/workflows/release-prod.yml deleted file mode 100644 index d9809ce..0000000 --- a/.github/workflows/release-prod.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Release Production - -on: - push: - tags: - - "v*" - - "!v*-dev*" # Exclude all dev tags - -permissions: - contents: write - id-token: write - -env: - NODE_VERSION: "20.x" - -jobs: - build-and-publish: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - fetch-depth: 0 - - - name: Set version from tag - run: | - VERSION="${{ github.ref_name }}" - # Clean leading v from provided version - PACKAGE_VERSION="${VERSION#v}" - # Extract base semantic version (x.y.z) - strip everything after first hyphen - BASE_VERSION="${VERSION%%-*}" - echo "VERSION=$VERSION" >> $GITHUB_ENV - echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV - echo "BASE_VERSION=$BASE_VERSION" >> $GITHUB_ENV - echo "Building production version: $PACKAGE_VERSION" - echo "Will verify dev tag exists for base version: $BASE_VERSION" - - - name: Verify dev testing occurred - run: | - echo "Looking for dev tag with base version: ${{ env.BASE_VERSION }}" - - # Check if any dev tag exists for this semantic version (e.g., v0.1.0-dev*) - DEV_TAGS=$(git tag -l "${{ env.BASE_VERSION }}-dev*" | head -10) - if [ -z "$DEV_TAGS" ]; then - echo "ERROR: No dev tag found for version ${{ env.BASE_VERSION }}" - echo "" - echo "Available dev tags:" - git tag -l "*-dev*" | head -10 || echo "No dev tags found" - echo "" - echo "Must test in dev first: git tag ${{ env.BASE_VERSION }}-dev" - exit 1 - fi - - echo "✅ Found dev tags for ${{ env.BASE_VERSION }}:" - echo "$DEV_TAGS" - - # Verify dev and prod tags point to same commit - PROD_COMMIT=$(git rev-list -n 1 "${{ github.ref_name }}") - echo "Production tag ${{ github.ref_name }} points to commit: $PROD_COMMIT" - - for DEV_TAG in $DEV_TAGS; do - DEV_COMMIT=$(git rev-list -n 1 "$DEV_TAG") - echo "Dev tag $DEV_TAG points to commit: $DEV_COMMIT" - - if [ "$DEV_COMMIT" = "$PROD_COMMIT" ]; then - echo "✅ Dev tag $DEV_TAG verified - same commit as production tag" - echo "VERIFIED_DEV_TAG=$DEV_TAG" >> $GITHUB_ENV - exit 0 - fi - done - - echo "ERROR: No dev tag points to the same commit as production tag ${{ github.ref_name }}" - echo "Production commit: $PROD_COMMIT" - echo "Dev tags and their commits:" - for DEV_TAG in $DEV_TAGS; do - DEV_COMMIT=$(git rev-list -n 1 "$DEV_TAG") - echo " $DEV_TAG: $DEV_COMMIT" - done - echo "" - echo "Create a dev tag on the same commit: git tag ${{ env.BASE_VERSION }}-dev $PROD_COMMIT" - exit 1 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - registry-url: "https://registry.npmjs.org" - cache: "pnpm" - - - name: Install dependencies - working-directory: . - run: pnpm install --frozen-lockfile - - - name: Build SDK (prod) - dependency for CLI - working-directory: ./packages/sdk - env: - BUILD_TYPE: prod - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - POSTHOG_API_KEY_BUILD_TIME: ${{ secrets.POSTHOG_API_KEY }} - run: | - pnpm run build - - - name: Build CLI (prod) - working-directory: ./packages/cli - env: - BUILD_TYPE: prod - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - POSTHOG_API_KEY_BUILD_TIME: ${{ secrets.POSTHOG_API_KEY }} - run: | - pnpm run build - - - name: Get short sha - run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV - env: - GITHUB_SHA: ${{ github.sha }} - - - name: Generate SDK VERSION file - working-directory: ./packages/sdk - env: - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - GITHUB_SHA: ${{ env.SHORT_SHA }} - run: | - node scripts/generate-version.js - - - name: Generate CLI VERSION file - working-directory: ./packages/cli - env: - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - GITHUB_SHA: ${{ env.SHORT_SHA }} - run: | - node scripts/generate-version.js - - - name: Update SDK package.json for publishing - working-directory: ./packages/sdk - run: | - # Update version (keep default package name) - npm pkg set version="${{ env.PACKAGE_VERSION }}" - - - name: Publish SDK to npm (prod) - working-directory: ./packages/sdk - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - npm publish --tag latest --access public - - - name: Update CLI package.json for publishing - working-directory: ./packages/cli - run: | - # Update version (keep default package name) - npm pkg set version="${{ env.PACKAGE_VERSION }}" - # Update SDK dependency to match published version - npm pkg set "dependencies.@layr-labs/ecloud-sdk"="${{ env.PACKAGE_VERSION }}" - # Verify changes - cat package.json | grep -A 2 '"name"' - cat package.json | grep -A 1 '"@layr-labs/ecloud-sdk"' - - - name: Publish CLI to npm (prod) - working-directory: ./packages/cli - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - npm publish --tag latest --access public - - - name: Summary - run: | - echo "🚀 Production release published successfully!" - echo "📦 SDK Package: @layr-labs/ecloud-sdk@${{ env.PACKAGE_VERSION }} (tag: latest)" - echo "📦 CLI Package: @layr-labs/ecloud-cli@${{ env.PACKAGE_VERSION }} (tag: latest)" - echo "🏷️ Tag: latest" - echo "🔒 Verified dev testing completed with matching commit from ${{ env.VERIFIED_DEV_TAG }}" - echo "🔗 Install with: npm install -g @layr-labs/ecloud-cli@latest" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6eae97e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,358 @@ +name: Release + +on: + push: + tags: + - "v*" + pull_request: + branches: + - main + - develop + workflow_dispatch: + inputs: + dry_run: + description: 'Run in dry-run mode (no publishing)' + required: false + type: boolean + default: true + +permissions: + contents: write + id-token: write + pull-requests: read + +env: + NODE_VERSION: "20.x" + PNPM_VERSION: "9" + +jobs: + test: + if: github.event_name == 'pull_request' + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "pnpm" + + - name: Show build info + run: make info + + - name: Install dependencies + run: make install + + - name: Run checks + run: make ci-check + + - name: Build packages + run: make build BUILD_TYPE=dev + + - name: Show package versions + run: make show-versions + + - name: Summary + run: | + echo "### PR Checks Passed" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "All linting, formatting, type checking, and build steps completed successfully." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Build Type:** dev" >> $GITHUB_STEP_SUMMARY + + dry-run: + if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: Detect version + run: | + VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.1-dev.manual") + PACKAGE_VERSION="${VERSION#v}" + + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV + + if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-dev ]]; then + echo "BUILD_TYPE=dev" >> $GITHUB_ENV + echo "NPM_TAG=dev" >> $GITHUB_ENV + else + echo "BUILD_TYPE=prod" >> $GITHUB_ENV + echo "NPM_TAG=latest" >> $GITHUB_ENV + fi + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: "pnpm" + + - name: Get short sha + run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV + env: + GITHUB_SHA: ${{ github.sha }} + + - name: Install dependencies + run: make install + + - name: Run checks + run: make ci-check + + - name: Build packages + env: + POSTHOG_API_KEY_BUILD_TIME: ${{ secrets.POSTHOG_API_KEY }} + run: | + make build \ + BUILD_TYPE=${{ env.BUILD_TYPE }} \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} + + - name: Generate VERSION files + run: | + make version \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ + SHORT_SHA=${{ env.SHORT_SHA }} + + - name: Prepare packages + run: | + make prepare \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} + + - name: Dry-run summary + run: | + make dry-run \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ + BUILD_TYPE=${{ env.BUILD_TYPE }} \ + NPM_TAG=${{ env.NPM_TAG }} + + - name: Summary + run: | + echo "### Dry-Run Complete (No Publishing)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Version:** \`${{ env.PACKAGE_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Build Type:** \`${{ env.BUILD_TYPE }}\`" >> $GITHUB_STEP_SUMMARY + echo "**NPM Tag:** \`${{ env.NPM_TAG }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Commit:** \`${{ env.SHORT_SHA }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Status:** Build and checks passed, but packages were NOT published." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "To publish, re-run with dry_run=false or push a version tag." >> $GITHUB_STEP_SUMMARY + + release: + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || + (github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false') + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: Determine release type and set variables + id: release-type + run: | + # Handle manual trigger vs tag push + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + # For manual triggers, use current commit and detect version from latest tag + VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.1-dev.manual") + echo "Manual trigger detected, using version: $VERSION" + echo "IS_MANUAL=true" >> $GITHUB_ENV + else + VERSION="${{ github.ref_name }}" + echo "Tag push detected: $VERSION" + echo "IS_MANUAL=false" >> $GITHUB_ENV + fi + + echo "VERSION=$VERSION" >> $GITHUB_ENV + + # Clean leading v from version + PACKAGE_VERSION="${VERSION#v}" + echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV + + # Determine if this is a dev or prod release + if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-dev ]]; then + echo "RELEASE_TYPE=dev" >> $GITHUB_ENV + echo "BUILD_TYPE=dev" >> $GITHUB_ENV + echo "NPM_TAG=dev" >> $GITHUB_ENV + echo "IS_DEV=true" >> $GITHUB_ENV + echo "IS_PROD=false" >> $GITHUB_ENV + echo "Detected DEV release: $PACKAGE_VERSION" + else + echo "RELEASE_TYPE=prod" >> $GITHUB_ENV + echo "BUILD_TYPE=prod" >> $GITHUB_ENV + echo "NPM_TAG=latest" >> $GITHUB_ENV + echo "IS_DEV=false" >> $GITHUB_ENV + echo "IS_PROD=true" >> $GITHUB_ENV + echo "Detected PRODUCTION release: $PACKAGE_VERSION" + + # Extract base version for prod releases + BASE_VERSION="${VERSION%%-*}" + echo "BASE_VERSION=$BASE_VERSION" >> $GITHUB_ENV + fi + + - name: Enforce dev tag format + if: env.IS_DEV == 'true' + run: | + VERSION="${{ env.VERSION }}" + if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-dev ]]; then + echo "Version '$VERSION' does not match required pattern v..-dev*" + exit 1 + fi + echo "Dev tag format validated" + + - name: Verify dev testing occurred + if: env.IS_PROD == 'true' + run: | + echo "Production release detected - verifying dev testing" + echo "Looking for dev tag with base version: ${{ env.BASE_VERSION }}" + + # Check if any dev tag exists for this semantic version + DEV_TAGS=$(git tag -l "${{ env.BASE_VERSION }}-dev*" | head -10) + if [ -z "$DEV_TAGS" ]; then + echo "ERROR: No dev tag found for version ${{ env.BASE_VERSION }}" + echo "" + echo "Available dev tags:" + git tag -l "*-dev*" | head -10 || echo "No dev tags found" + echo "" + echo "Must test in dev first: git tag ${{ env.BASE_VERSION }}-dev" + exit 1 + fi + + echo "Found dev tags for ${{ env.BASE_VERSION }}:" + echo "$DEV_TAGS" + + # Verify dev and prod tags point to same commit + PROD_COMMIT=$(git rev-list -n 1 "${{ github.ref_name }}") + echo "Production tag ${{ github.ref_name }} points to commit: $PROD_COMMIT" + + for DEV_TAG in $DEV_TAGS; do + DEV_COMMIT=$(git rev-list -n 1 "$DEV_TAG") + echo "Dev tag $DEV_TAG points to commit: $DEV_COMMIT" + + if [ "$DEV_COMMIT" = "$PROD_COMMIT" ]; then + echo "Dev tag $DEV_TAG verified - same commit as production tag" + echo "VERIFIED_DEV_TAG=$DEV_TAG" >> $GITHUB_ENV + exit 0 + fi + done + + echo "ERROR: No dev tag points to the same commit as production tag ${{ github.ref_name }}" + echo "Production commit: $PROD_COMMIT" + echo "Dev tags and their commits:" + for DEV_TAG in $DEV_TAGS; do + DEV_COMMIT=$(git rev-list -n 1 "$DEV_TAG") + echo " $DEV_TAG: $DEV_COMMIT" + done + echo "" + echo "Create a dev tag on the same commit: git tag ${{ env.BASE_VERSION }}-dev $PROD_COMMIT" + exit 1 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + + - name: Get short sha + run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV + env: + GITHUB_SHA: ${{ github.sha }} + + - name: Validate version + run: make validate-version PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} + + - name: Install dependencies + run: make install + + - name: Run checks + run: make ci-check + + - name: Build packages + env: + POSTHOG_API_KEY_BUILD_TIME: ${{ secrets.POSTHOG_API_KEY }} + run: | + make build \ + BUILD_TYPE=${{ env.BUILD_TYPE }} \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} + + - name: Generate VERSION files + run: | + make version \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ + SHORT_SHA=${{ env.SHORT_SHA }} + + - name: Prepare packages for publishing + run: | + make prepare \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} + + - name: Show versions before publish + run: make show-versions PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} BUILD_TYPE=${{ env.BUILD_TYPE }} NPM_TAG=${{ env.NPM_TAG }} + + - name: Publish packages to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + make publish \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ + NPM_TAG=${{ env.NPM_TAG }} + + - name: Summary (Dev) + if: env.IS_DEV == 'true' + run: | + echo "### Dev Release Published" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Version:** \`${{ env.PACKAGE_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + echo "**NPM Tag:** \`dev\`" >> $GITHUB_STEP_SUMMARY + echo "**Commit:** \`${{ env.SHORT_SHA }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Packages:**" >> $GITHUB_STEP_SUMMARY + echo "- [@layr-labs/ecloud-sdk@${{ env.PACKAGE_VERSION }}](https://www.npmjs.com/package/@layr-labs/ecloud-sdk)" >> $GITHUB_STEP_SUMMARY + echo "- [@layr-labs/ecloud-cli@${{ env.PACKAGE_VERSION }}](https://www.npmjs.com/package/@layr-labs/ecloud-cli)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Install:**" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY + echo "npm install -g @layr-labs/ecloud-cli@dev" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + + - name: Summary (Prod) + if: env.IS_PROD == 'true' + run: | + echo "### Production Release Published" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Version:** \`${{ env.PACKAGE_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + echo "**NPM Tag:** \`latest\`" >> $GITHUB_STEP_SUMMARY + echo "**Commit:** \`${{ env.SHORT_SHA }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Verified Dev Tag:** \`${{ env.VERIFIED_DEV_TAG }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Packages:**" >> $GITHUB_STEP_SUMMARY + echo "- [@layr-labs/ecloud-sdk@${{ env.PACKAGE_VERSION }}](https://www.npmjs.com/package/@layr-labs/ecloud-sdk)" >> $GITHUB_STEP_SUMMARY + echo "- [@layr-labs/ecloud-cli@${{ env.PACKAGE_VERSION }}](https://www.npmjs.com/package/@layr-labs/ecloud-cli)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Install:**" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY + echo "npm install -g @layr-labs/ecloud-cli@latest" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..33649bf --- /dev/null +++ b/Makefile @@ -0,0 +1,227 @@ +# Makefile for eCloud SDK and CLI + +.PHONY: help install clean build test lint format typecheck ci-check +.PHONY: version prepare publish dry-run validate-version show-versions info +.PHONY: build-sdk build-cli + +.DEFAULT_GOAL := help + +# Build configuration +PACKAGE_VERSION ?= 0.0.1-dev.local +BUILD_TYPE ?= dev +NPM_TAG ?= dev +SHORT_SHA ?= local +NODE_ENV ?= production + +SDK_DIR := packages/sdk +CLI_DIR := packages/cli + +# Terminal colors +CYAN := \033[0;36m +GREEN := \033[0;32m +RED := \033[0;31m +YELLOW := \033[0;33m +NC := \033[0m + +##@ General + +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +info: ## Show build environment information + @echo "$(CYAN)Build Environment:$(NC)" + @echo " Node: $$(node --version)" + @echo " pnpm: $$(pnpm --version)" + @echo " Type: $(BUILD_TYPE)" + @echo " Version: $(PACKAGE_VERSION)" + @echo " Tag: $(NPM_TAG)" + @echo " SHA: $(SHORT_SHA)" + +##@ Dependencies + +install: ## Install all dependencies + @echo "$(CYAN)Installing dependencies...$(NC)" + @pnpm install --frozen-lockfile + +clean: ## Clean build artifacts and node_modules + @echo "$(CYAN)Cleaning...$(NC)" + @rm -rf $(SDK_DIR)/dist + @rm -rf $(CLI_DIR)/dist + @rm -f $(SDK_DIR)/VERSION + @rm -f $(CLI_DIR)/VERSION + @rm -f $(SDK_DIR)/README.md + @rm -f $(CLI_DIR)/README.md + @echo "$(GREEN)Done$(NC)" + +clean-all: clean ## Clean everything including node_modules + @rm -rf node_modules + @rm -rf $(SDK_DIR)/node_modules + @rm -rf $(CLI_DIR)/node_modules + @echo "$(GREEN)All clean$(NC)" + +##@ Code Quality + +lint: ## Run linter on all packages + @pnpm run lint + +format: ## Check code formatting + @pnpm run format + +format-fix: ## Fix code formatting issues + @pnpm run format:fix + +typecheck: ## Run TypeScript type checking + @pnpm run typecheck + +test: ## Run tests + @pnpm run test + +ci-check: lint format typecheck ## Run all CI checks (lint, format, typecheck) + @echo "$(GREEN)CI checks passed$(NC)" + +##@ Build + +build-sdk: ## Build SDK package + @echo "$(CYAN)Building SDK ($(BUILD_TYPE))...$(NC)" + @cd $(SDK_DIR) && \ + BUILD_TYPE=$(BUILD_TYPE) \ + PACKAGE_VERSION=$(PACKAGE_VERSION) \ + POSTHOG_API_KEY_BUILD_TIME=$(POSTHOG_API_KEY_BUILD_TIME) \ + pnpm run build + +build-cli: build-sdk ## Build CLI package (depends on SDK) + @echo "$(CYAN)Building CLI ($(BUILD_TYPE))...$(NC)" + @cd $(CLI_DIR) && \ + BUILD_TYPE=$(BUILD_TYPE) \ + PACKAGE_VERSION=$(PACKAGE_VERSION) \ + POSTHOG_API_KEY_BUILD_TIME=$(POSTHOG_API_KEY_BUILD_TIME) \ + pnpm run build + +build: build-cli ## Build all packages (SDK + CLI) + @echo "$(GREEN)Build complete$(NC)" + +##@ Version Management + +version: ## Generate VERSION files for both packages + @echo "$(CYAN)Generating VERSION files...$(NC)" + @cd $(SDK_DIR) && \ + PACKAGE_VERSION=$(PACKAGE_VERSION) \ + GITHUB_SHA=$(SHORT_SHA) \ + node scripts/generate-version.js + @cd $(CLI_DIR) && \ + PACKAGE_VERSION=$(PACKAGE_VERSION) \ + GITHUB_SHA=$(SHORT_SHA) \ + node scripts/generate-version.js + +validate-version: ## Validate version format + @echo "Validating version: $(PACKAGE_VERSION)" + @if echo "$(PACKAGE_VERSION)" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then \ + echo "$(GREEN)Valid version format$(NC)"; \ + else \ + echo "$(RED)Invalid version: $(PACKAGE_VERSION)$(NC)"; \ + echo "Expected format: x.y.z or x.y.z-prerelease"; \ + exit 1; \ + fi + +show-versions: ## Show current package versions + @echo "$(CYAN)Package Versions:$(NC)" + @echo " SDK: $$(cd $(SDK_DIR) && node -p "require('./package.json').version")" + @echo " CLI: $$(cd $(CLI_DIR) && node -p "require('./package.json').version")" + @if [ -f "$(SDK_DIR)/VERSION" ]; then \ + echo " SDK VERSION file: $$(cat $(SDK_DIR)/VERSION)"; \ + fi + @if [ -f "$(CLI_DIR)/VERSION" ]; then \ + echo " CLI VERSION file: $$(cat $(CLI_DIR)/VERSION)"; \ + fi + @echo "" + @echo "Build config: $(PACKAGE_VERSION) ($(BUILD_TYPE), tag=$(NPM_TAG))" + +##@ Publishing + +prepare: ## Prepare packages for publishing (update versions and dependencies) + @echo "$(CYAN)Preparing packages...$(NC)" + @echo "Setting version to $(PACKAGE_VERSION)" + @cd $(SDK_DIR) && npm pkg set version="$(PACKAGE_VERSION)" + @cd $(CLI_DIR) && npm pkg set version="$(PACKAGE_VERSION)" + @cd $(CLI_DIR) && npm pkg set "dependencies.@layr-labs/ecloud-sdk"="$(PACKAGE_VERSION)" + @echo "" + @echo "SDK:" + @cd $(SDK_DIR) && cat package.json | grep -A 2 '"name"' + @echo "" + @echo "CLI:" + @cd $(CLI_DIR) && cat package.json | grep -A 2 '"name"' + @cd $(CLI_DIR) && cat package.json | grep -A 1 '"@layr-labs/ecloud-sdk"' + @echo "" + @echo "$(GREEN)Ready to publish$(NC)" + +dry-run: ## Show what would be published without actually publishing + @echo "$(YELLOW)DRY RUN - Nothing will be published$(NC)" + @echo "" + @echo "Config:" + @echo " Version: $(PACKAGE_VERSION)" + @echo " Type: $(BUILD_TYPE)" + @echo " Tag: $(NPM_TAG)" + @echo " SHA: $(SHORT_SHA)" + @echo "" + @echo "Would publish:" + @echo " - @layr-labs/ecloud-sdk@$(PACKAGE_VERSION)" + @echo " - @layr-labs/ecloud-cli@$(PACKAGE_VERSION)" + @echo "" + @echo "To publish: make publish PACKAGE_VERSION=$(PACKAGE_VERSION) NPM_TAG=$(NPM_TAG)" + @echo "" + +publish: ## Publish packages to npm + @echo "$(CYAN)Publishing to npm...$(NC)" + @echo "Publishing SDK (tag=$(NPM_TAG))" + @cd $(SDK_DIR) && npm publish --tag $(NPM_TAG) --access public + @echo "Publishing CLI (tag=$(NPM_TAG))" + @cd $(CLI_DIR) && npm publish --tag $(NPM_TAG) --access public + @echo "" + @echo "$(GREEN)Published:$(NC)" + @echo " @layr-labs/ecloud-sdk@$(PACKAGE_VERSION)" + @echo " @layr-labs/ecloud-cli@$(PACKAGE_VERSION)" + @echo "" + @if [ "$(NPM_TAG)" = "latest" ]; then \ + echo "Install: npm install -g @layr-labs/ecloud-cli"; \ + else \ + echo "Install: npm install -g @layr-labs/ecloud-cli@$(NPM_TAG)"; \ + fi + @echo "" + +##@ Local Development + +dev-build: ## Quick build for local development + @$(MAKE) build BUILD_TYPE=dev PACKAGE_VERSION=0.0.1-dev.local + +dev-install: install dev-build ## Install and build for local development + @echo "$(GREEN)Dev environment ready$(NC)" + +dev-test: ci-check test ## Run all checks and tests + @echo "$(GREEN)All checks passed$(NC)" + +##@ Release Workflows + +release-dev: ## Complete dev release workflow (build, version, prepare) + @$(MAKE) validate-version PACKAGE_VERSION=$(PACKAGE_VERSION) + @$(MAKE) install + @$(MAKE) ci-check + @$(MAKE) build BUILD_TYPE=dev + @$(MAKE) version + @$(MAKE) prepare + @$(MAKE) show-versions + @echo "$(GREEN)Ready to publish dev release$(NC)" + +release-prod: ## Complete prod release workflow (build, version, prepare) + @$(MAKE) validate-version PACKAGE_VERSION=$(PACKAGE_VERSION) + @$(MAKE) install + @$(MAKE) ci-check + @$(MAKE) build BUILD_TYPE=prod + @$(MAKE) version + @$(MAKE) prepare + @$(MAKE) show-versions + @echo "$(GREEN)Ready to publish production release$(NC)" + +##@ Documentation + +docs: ## Generate documentation + @echo "$(YELLOW)Documentation generation not implemented yet$(NC)" diff --git a/README.md b/README.md index 8376243..384a6e4 100644 --- a/README.md +++ b/README.md @@ -361,8 +361,25 @@ ecloud-sdk/ └── pnpm-workspace.yaml ``` +### Build System + +This project uses a Makefile for consistent build and release workflows. The Makefile provides a standardized interface that works both locally and in CI/CD. + +**Quick commands:** + +```bash +make help # Show all available commands +make dev # Install dependencies, run checks, and build +make build # Build all packages +make check # Run all checks (lint, format, typecheck, test) +``` + +**For complete documentation, see [MAKEFILE.md](./MAKEFILE.md)** + ### Scripts +You can also use pnpm scripts directly: + - `pnpm build` - Build all packages - `pnpm lint` - Lint all packages - `pnpm format` - Check code formatting @@ -370,6 +387,8 @@ ecloud-sdk/ - `pnpm test` - Run tests (when implemented) - `pnpm ecloud` - Run the CLI +**Note:** The Makefile is the recommended way to build and test, as it matches the CI/CD pipeline exactly. + ### Adding New Commands 1. Create a new command file in `packages/cli/src/commands/` @@ -393,6 +412,97 @@ The deployment process involves several steps: 5. **On-Chain Deployment**: Deploy smart contract with app configuration 6. **Status Monitoring**: Watch until application is running +## Release Process + +This repository uses a two-stage release process with automated CI/CD via GitHub Actions: + +### Dev Release (Testing) + +1. Create a dev tag with format `v..-dev`: + ```bash + git tag v0.2.0-dev.1 + git push origin v0.2.0-dev.1 + ``` + +2. The CI pipeline automatically: + - Validates the tag format + - Runs all checks (lint, format, typecheck, test) + - Builds SDK and CLI packages with `BUILD_TYPE=dev` + - Publishes to npm with `dev` tag + +3. Test the dev release: + ```bash + npm install -g @layr-labs/ecloud-cli@dev + ``` + +### Production Release + +1. After testing the dev release, create a production tag: + ```bash + # Must use the same base version as the dev tag + git tag v0.2.0 + git push origin v0.2.0 + ``` + +2. The CI pipeline automatically: + - Verifies a corresponding dev tag exists (e.g., `v0.2.0-dev*`) + - Verifies the dev and prod tags point to the same commit + - Runs all checks + - Builds SDK and CLI packages with `BUILD_TYPE=prod` + - Publishes to npm with `latest` tag + +3. Install the production release: + ```bash + npm install -g @layr-labs/ecloud-cli@latest + ``` + +### Release Candidate (Optional) + +For additional testing before final production release, you can use release candidate tags: + +```bash +# After dev testing, create an RC +git tag v0.2.0-rc.1 +git push origin v0.2.0-rc.1 + +# This publishes to 'latest' with version 0.2.0-rc.1 +# Test thoroughly, then create final production tag +git tag v0.2.0 +git push origin v0.2.0 +``` + +### Local Release Testing + +To test the release process locally before pushing tags: + +```bash +# Test a dev build +make release \ + BUILD_TYPE=dev \ + PACKAGE_VERSION=0.2.0-dev.1 \ + SHORT_SHA=$(git rev-parse --short HEAD) \ + NPM_TAG=dev + +# Test a prod build +make release \ + BUILD_TYPE=prod \ + PACKAGE_VERSION=0.2.0 \ + SHORT_SHA=$(git rev-parse --short HEAD) \ + NPM_TAG=latest +``` + +**Note:** Local testing won't actually publish to npm unless you set `NODE_AUTH_TOKEN`. + +### Pull Request Testing + +The CI pipeline automatically runs checks and builds on all pull requests to `main` or `develop` branches: + +- Runs all linting, formatting, and type checking +- Builds packages with `BUILD_TYPE=dev` +- Reports any failures before merge + +For more details on the Makefile commands used in releases, see [MAKEFILE.md](./MAKEFILE.md). + ## Security - Private keys are never stored or logged @@ -402,11 +512,60 @@ The deployment process involves several steps: ## Contributing -1. Fork the repository -2. Create a feature branch -3. Make your changes -4. Run tests and linting -5. Submit a pull request +We welcome contributions! Here's how to get started: + +1. **Fork and Clone** + ```bash + git clone + cd ecloud + ``` + +2. **Setup Development Environment** + ```bash + make install # Install dependencies + make check # Run all checks + make build # Build packages + ``` + +3. **Make Your Changes** + ```bash + git checkout -b feature/my-feature + # Make your changes... + make pre-commit # Format and check before committing + ``` + +4. **Submit Pull Request** + - Push your branch and create a PR + - Automated tests will run on your PR + - Address any feedback from reviewers + +### Development Documentation + +For detailed development and release workflows: + +- **[Workflow Guide](./WORKFLOW_GUIDE.md)** - Complete developer workflow guide +- **[Release Architecture](./RELEASE_ARCHITECTURE.md)** - System architecture and flows +- **[Build and Release](./BUILD_AND_RELEASE.md)** - Detailed build system documentation +- **[Makefile Reference](./MAKEFILE.md)** - All Makefile commands explained +- **[GitHub Workflows](./.github/workflows/README.md)** - CI/CD pipeline documentation + +### Quick Commands + +```bash +# Development +make dev # Install, check, and build +make quick-build # Fast build without checks +make pre-commit # Format and check before commit + +# Testing +make check # Run all quality checks +make lint # Run linter +make typecheck # Run type checking + +# Information +make info # Show build system info +make help # List all commands +``` ## Support