diff --git a/.github/workflows/publish.puppetforge.yml b/.github/workflows/publish.puppetforge.yml index 1c37b1a4d..b72dc5f17 100644 --- a/.github/workflows/publish.puppetforge.yml +++ b/.github/workflows/publish.puppetforge.yml @@ -1,22 +1,93 @@ name: Publish to Puppet Forge - on: workflow_dispatch: - release: - types: [published] jobs: - security-scan: - name: Security Scan + generate-sbom: runs-on: ubuntu-latest - + steps: + - name: Get the source code + uses: actions/checkout@v3 + + - name: Install Syft + run: | + echo "Installing Syft v1.18.1..." + curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /tmp/bin v1.18.1 + echo "/tmp/bin" >> $GITHUB_PATH + + - name: Install Manifest CLI + run: | + echo "Installing Manifest CLI v0.18.3..." + curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -s -- -b /tmp/bin v0.18.3 + + - name: Create Syft configuration + run: | + cat > syft-config.yaml << 'EOF' + package: + search: + scope: all-layers + exclude: + - "**/spec/**" + - "**/examples/**" + - "**/tests/**" + cataloger: + enabled: true + ruby: + enabled: true + search-gems: true + java: + enabled: false + python: + enabled: false + nodejs: + enabled: false + EOF + + - name: Generate and upload SBOM + env: + MANIFEST_API_KEY: ${{ secrets.MANIFEST_TOKEN }} + run: | + PUPPET_MODULE_DIR="./integration/keeper_secrets_manager_puppet" + + # Get version from metadata.json + echo "Detecting Puppet module version..." + if [ -f "${PUPPET_MODULE_DIR}/metadata.json" ]; then + VERSION=$(cat "${PUPPET_MODULE_DIR}/metadata.json" | jq -r .version) + echo "Detected version: ${VERSION}" + else + VERSION="1.0.0" + echo "Could not detect version, using default: ${VERSION}" + fi + + echo "Generating SBOM with Manifest CLI..." + /tmp/bin/manifest sbom "${PUPPET_MODULE_DIR}" \ + --generator=syft \ + --name=keeper-secrets-manager-puppet \ + --version=${VERSION} \ + --output=spdx-json \ + --file=puppet-module-sbom.json \ + --api-key=${MANIFEST_API_KEY} \ + --publish=true \ + --asset-label=application,sbom-generated,ruby,puppet \ + --generator-config=syft-config.yaml + + echo "SBOM generated and uploaded successfully: puppet-module-sbom.json" + echo "---------- SBOM Preview (first 20 lines) ----------" + head -n 20 puppet-module-sbom.json + + publish-puppet-forge: + needs: generate-sbom + environment: prod + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: run: working-directory: ./integration/keeper_secrets_manager_puppet steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Get the source code + uses: actions/checkout@v3 - name: Setup Ruby uses: ruby/setup-ruby@v1 @@ -29,6 +100,14 @@ jobs: run: | bundle install + - name: Retrieve secrets from KSM + id: ksmsecrets + uses: Keeper-Security/ksm-action@master + with: + keeper-secret-config: ${{ secrets.KSM_KSM_CONFIG }} + secrets: | + _gC1qMMHRcD6Fztyd692kw/field/password > PUPPET_FORGE_API_KEY + - name: Run Puppet Lint run: | bundle exec puppet-lint \ @@ -46,91 +125,17 @@ jobs: run: | bundle exec metadata-json-lint metadata.json - - name: Security scan for Ruby dependencies - run: | - gem install bundler-audit - bundle audit check --update - - - name: Check for hardcoded secrets - run: | - # Check for potential secrets in manifests - echo "Checking for hardcoded secrets..." - ! grep -rE "(password|secret|token|key)\s*=\s*['\"][^'\"]+['\"]" manifests/ || { - echo "::error::Found potential hardcoded secrets in manifests" - exit 1 - } - - name: Run RSpec tests run: | bundle exec rake spec - publish: - name: Build and Publish to Puppet Forge - needs: security-scan - environment: prod - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ./integration/keeper_secrets_manager_puppet - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2' - bundler-cache: true - working-directory: ./integration/keeper_secrets_manager_puppet - - - name: Install dependencies - run: | - bundle install - - - name: Retrieve secrets from KSM - id: ksmsecrets - uses: Keeper-Security/ksm-action@master - with: - keeper-secret-config: ${{ secrets.KSM_PUPPET_FORGE_CONFIG }} - secrets: | - _gC1qMMHRcD6Fztyd692kw/field/password > PUPPET_FORGE_API_KEY - - name: Build module run: | bundle exec pdk build - - name: Generate SBOM - uses: anchore/sbom-action@v0 - with: - path: ./integration/keeper_secrets_manager_puppet - format: cyclonedx-json - output-file: puppet-module-sbom.json - - - name: Upload SBOM - uses: actions/upload-artifact@v4 - with: - name: puppet-module-sbom - path: puppet-module-sbom.json - retention-days: 90 - - name: Publish to Puppet Forge env: PDK_DISABLE_ANALYTICS: true run: | # Use PDK to publish with API key - bundle exec pdk release publish --forge-token=${{ steps.ksmsecrets.outputs.PUPPET_FORGE_API_KEY }} --force - - - name: Create GitHub Release Assets - if: github.event_name == 'release' - run: | - # Find the built module - MODULE_FILE=$(find pkg -name "*.tar.gz" | head -1) - - # Upload to GitHub release - gh release upload ${{ github.event.release.tag_name }} \ - "${MODULE_FILE}" \ - --clobber - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + bundle exec pdk release publish --forge-token=${{ secrets.PUPPET_FORGE_API_KEY }} --force \ No newline at end of file