-
Notifications
You must be signed in to change notification settings - Fork 56
Releasing Puppet integration v1.0.2 #776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
b2903c0
4771490
a6f4df6
e05652e
86d96a6
b14cf98
61be570
47f585e
7c0d343
df2797c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,309 @@ | ||||||||||||||||||||
name: Publish to Puppet Forge | ||||||||||||||||||||
on: | ||||||||||||||||||||
workflow_dispatch: | ||||||||||||||||||||
|
||||||||||||||||||||
jobs: | ||||||||||||||||||||
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: 15 | ||||||||||||||||||||
|
||||||||||||||||||||
defaults: | ||||||||||||||||||||
run: | ||||||||||||||||||||
working-directory: ./integration/keeper_secrets_manager_puppet | ||||||||||||||||||||
|
||||||||||||||||||||
steps: | ||||||||||||||||||||
- name: Get the source code | ||||||||||||||||||||
uses: actions/checkout@v4 | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Setup Ruby with version from .ruby-version | ||||||||||||||||||||
uses: ruby/setup-ruby@v1 | ||||||||||||||||||||
with: | ||||||||||||||||||||
ruby-version: '3.2.4' | ||||||||||||||||||||
bundler-cache: true | ||||||||||||||||||||
working-directory: ./integration/keeper_secrets_manager_puppet | ||||||||||||||||||||
|
||||||||||||||||||||
- 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: Get current version and validate | ||||||||||||||||||||
id: version | ||||||||||||||||||||
run: | | ||||||||||||||||||||
if [[ -f "metadata.json" ]]; then | ||||||||||||||||||||
VERSION=$(grep '"version"' metadata.json | cut -d'"' -f4) | ||||||||||||||||||||
echo "current_version=$VERSION" >> $GITHUB_OUTPUT | ||||||||||||||||||||
echo "Current version: $VERSION" | ||||||||||||||||||||
else | ||||||||||||||||||||
echo "Error: metadata.json not found" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Check if version already exists on Puppet Forge | ||||||||||||||||||||
env: | ||||||||||||||||||||
VERSION: ${{ steps.version.outputs.current_version }} | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "Checking if version $VERSION already exists on Puppet Forge..." | ||||||||||||||||||||
FORGE_CHECK=$(curl -s "https://forgeapi.puppet.com/v3/releases/keepersecurity-keeper_secrets_manager_puppet-$VERSION") | ||||||||||||||||||||
|
||||||||||||||||||||
if echo "$FORGE_CHECK" | grep -q '"uri"'; then | ||||||||||||||||||||
echo "Error: Version $VERSION already exists on Puppet Forge!" | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "To publish a new release, you need to:" | ||||||||||||||||||||
echo "1. Bump the version in metadata.json" | ||||||||||||||||||||
echo " File: integration/keeper_secrets_manager_puppet/metadata.json" | ||||||||||||||||||||
echo " Current: \"version\": \"$VERSION\"" | ||||||||||||||||||||
echo " Example: \"version\": \"1.0.3\" (for patch)" | ||||||||||||||||||||
echo " \"version\": \"1.1.0\" (for minor)" | ||||||||||||||||||||
echo " \"version\": \"2.0.0\" (for major)" | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "Version already published at: https://forge.puppet.com/modules/keepersecurity/keeper_secrets_manager_puppet" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "Version $VERSION is available for publishing" | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Validate API key format | ||||||||||||||||||||
env: | ||||||||||||||||||||
PUPPET_FORGE_API_KEY: ${{ steps.ksmsecrets.outputs.PUPPET_FORGE_API_KEY }} | ||||||||||||||||||||
run: | | ||||||||||||||||||||
if [[ ! "$PUPPET_FORGE_API_KEY" =~ ^[a-f0-9]{64}$ ]]; then | ||||||||||||||||||||
echo "Warning: API key format doesn't match expected pattern (64 hex characters)" | ||||||||||||||||||||
echo "Key length: ${#PUPPET_FORGE_API_KEY}" | ||||||||||||||||||||
echo "Continuing anyway, but check your key if publishing fails..." | ||||||||||||||||||||
else | ||||||||||||||||||||
echo "API key format looks correct" | ||||||||||||||||||||
fi | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Install dependencies | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "Installing Ruby dependencies..." | ||||||||||||||||||||
if ! bundle install; then | ||||||||||||||||||||
echo "Failed to install dependencies" | ||||||||||||||||||||
echo "Gem versions installed:" | ||||||||||||||||||||
bundle list | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "Dependencies installed successfully" | ||||||||||||||||||||
|
||||||||||||||||||||
# Show key dependency versions | ||||||||||||||||||||
echo "Key dependency versions:" | ||||||||||||||||||||
bundle list | grep -E "(puppet|rake|puppet-lint)" | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Run comprehensive validation | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "Running comprehensive validation..." | ||||||||||||||||||||
|
||||||||||||||||||||
# Run lint with error handling | ||||||||||||||||||||
echo "Running puppet-lint..." | ||||||||||||||||||||
if ! bundle exec rake lint; then | ||||||||||||||||||||
echo "Lint failed" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "Lint passed" | ||||||||||||||||||||
|
||||||||||||||||||||
# Run validation | ||||||||||||||||||||
echo "Running puppet validate..." | ||||||||||||||||||||
if ! bundle exec rake validate; then | ||||||||||||||||||||
echo "Validation failed" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "Validation passed" | ||||||||||||||||||||
|
||||||||||||||||||||
# Run metadata lint | ||||||||||||||||||||
echo "Running metadata lint..." | ||||||||||||||||||||
if ! bundle exec metadata-json-lint metadata.json; then | ||||||||||||||||||||
echo "Metadata lint failed" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "Metadata validation passed" | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Run full test suite | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "Running full test suite..." | ||||||||||||||||||||
if ! bundle exec rake spec; then | ||||||||||||||||||||
echo "Tests failed" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "All tests passed" | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Build module | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "Building module..." | ||||||||||||||||||||
if ! bundle exec rake module:build; then | ||||||||||||||||||||
echo "Build failed" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
echo "Module built successfully" | ||||||||||||||||||||
|
||||||||||||||||||||
# Show built packages | ||||||||||||||||||||
echo "Built packages:" | ||||||||||||||||||||
ls -la pkg/ | grep '.tar.gz' || echo "No packages found" | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Publish to Puppet Forge with robust error handling | ||||||||||||||||||||
env: | ||||||||||||||||||||
PUPPET_FORGE_API_KEY: ${{ steps.ksmsecrets.outputs.PUPPET_FORGE_API_KEY }} | ||||||||||||||||||||
VERSION: ${{ steps.version.outputs.current_version }} | ||||||||||||||||||||
PDK_DISABLE_ANALYTICS: true | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "Publishing to Puppet Forge..." | ||||||||||||||||||||
|
||||||||||||||||||||
cd pkg | ||||||||||||||||||||
LATEST_FILE=$(ls -t keepersecurity-keeper_secrets_manager_puppet-*.tar.gz | head -1) | ||||||||||||||||||||
|
||||||||||||||||||||
if [[ -z "$LATEST_FILE" ]]; then | ||||||||||||||||||||
echo "No package file found to publish" | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
|
||||||||||||||||||||
echo "Publishing: $LATEST_FILE" | ||||||||||||||||||||
|
||||||||||||||||||||
RESULT=$(curl -s -X POST \ | ||||||||||||||||||||
-H "Authorization: Bearer $PUPPET_FORGE_API_KEY" \ | ||||||||||||||||||||
-F "file=@$LATEST_FILE" \ | ||||||||||||||||||||
https://forgeapi.puppet.com/v3/releases) | ||||||||||||||||||||
|
||||||||||||||||||||
echo "$RESULT" | ||||||||||||||||||||
|
||||||||||||||||||||
if echo "$RESULT" | grep -q '"uri"'; then | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "Successfully published to Puppet Forge!" | ||||||||||||||||||||
echo "Module available at: https://forge.puppet.com/modules/keepersecurity/keeper_secrets_manager_puppet" | ||||||||||||||||||||
|
||||||||||||||||||||
# Extract and display the published version info | ||||||||||||||||||||
if echo "$RESULT" | grep -q '"version"'; then | ||||||||||||||||||||
PUBLISHED_VERSION=$(echo "$RESULT" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) | ||||||||||||||||||||
echo "Published version: $PUBLISHED_VERSION" | ||||||||||||||||||||
fi | ||||||||||||||||||||
else | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "Failed to publish. Check the error message above." | ||||||||||||||||||||
|
||||||||||||||||||||
# Enhanced error handling with specific guidance | ||||||||||||||||||||
if echo "$RESULT" | grep -q 'cannot publish releases'; then | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "API Key Issue: Your API key may not have permission to publish to the keepersecurity namespace." | ||||||||||||||||||||
echo "Solutions:" | ||||||||||||||||||||
echo "1. Verify you are using the correct API key from the keepersecurity organization" | ||||||||||||||||||||
echo "2. Check that your API key has publish permissions" | ||||||||||||||||||||
echo "3. Regenerate your API key at: https://forge.puppet.com/organization/api-keys" | ||||||||||||||||||||
echo "4. Update the secret in GitHub: PUPPET_FORGE_API_KEY" | ||||||||||||||||||||
elif echo "$RESULT" | grep -q -i 'version.*already.*exists\|duplicate.*version\|version.*conflict'; then | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "Version Conflict: This version already exists on Puppet Forge." | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "To publish a new release:" | ||||||||||||||||||||
echo "1. Bump the version in metadata.json" | ||||||||||||||||||||
echo " File: integration/keeper_secrets_manager_puppet/metadata.json" | ||||||||||||||||||||
echo " Current: \"version\": \"$VERSION\"" | ||||||||||||||||||||
echo " Example: \"version\": \"1.0.3\" (patch), \"1.1.0\" (minor), \"2.0.0\" (major)" | ||||||||||||||||||||
echo "2. Commit and push the version change" | ||||||||||||||||||||
echo "3. Re-run this workflow" | ||||||||||||||||||||
elif echo "$RESULT" | grep -q -i 'unauthorized\|authentication'; then | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "Authentication Error: API key is invalid or expired." | ||||||||||||||||||||
echo "Solutions:" | ||||||||||||||||||||
echo "1. Check that PUPPET_FORGE_API_KEY secret is set correctly" | ||||||||||||||||||||
echo "2. Regenerate API key at: https://forge.puppet.com/organization/api-keys" | ||||||||||||||||||||
echo "3. Update the GitHub secret with the new key" | ||||||||||||||||||||
else | ||||||||||||||||||||
echo "" | ||||||||||||||||||||
echo "Unknown error occurred. Please check the API response above." | ||||||||||||||||||||
echo "For help, visit: https://forge.puppet.com/docs/publish" | ||||||||||||||||||||
fi | ||||||||||||||||||||
exit 1 | ||||||||||||||||||||
fi | ||||||||||||||||||||
|
||||||||||||||||||||
- name: Create release summary | ||||||||||||||||||||
env: | ||||||||||||||||||||
VERSION: ${{ steps.version.outputs.current_version }} | ||||||||||||||||||||
run: | | ||||||||||||||||||||
echo "## Puppet Module Published Successfully!" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "**Version:** $VERSION" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "**Module:** keepersecurity-keeper_secrets_manager_puppet" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "**Forge URL:** https://forge.puppet.com/modules/keepersecurity/keeper_secrets_manager_puppet" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "### Validation Results" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "- Puppet Lint: Passed" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "- Puppet Validate: Passed" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "- Metadata Lint: Passed" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "- Test Suite: Passed" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "- Module Build: Successful" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
echo "- Forge Publish: Successful" >> $GITHUB_STEP_SUMMARY | ||||||||||||||||||||
Comment on lines
+79
to
+309
Check warningCode scanning / CodeQL Workflow does not contain permissions Medium
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Copilot AutofixAI 3 months ago To fix the problem, add a
Suggested changeset
1
.github/workflows/publish.puppetforge.yml
Copilot is powered by AI and may make mistakes. Always verify output.
Positive FeedbackNegative Feedback
Refresh and try again.
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# This file can be used to install module dependencies for unit testing | ||
# See https://github.com/puppetlabs/puppetlabs_spec_helper#using-fixtures for details | ||
--- | ||
fixtures: | ||
forge_modules: | ||
stdlib: | ||
repo: "puppetlabs/stdlib" | ||
ref: "9.2.0" | ||
repositories: | ||
stdlib: | ||
repo: "https://github.com/puppetlabs/puppetlabs-stdlib.git" | ||
ref: "v9.2.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.rb eol=lf | ||
*.erb eol=lf | ||
*.pp eol=lf | ||
*.sh eol=lf | ||
*.epp eol=lf |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Copilot Autofix
AI 3 months ago
To fix the problem, add a
permissions
block to the workflow file to explicitly set the minimum required permissions for the GITHUB_TOKEN. Since the workflow does not appear to require write access to repository contents or other resources, the minimal permission ofcontents: read
is appropriate. This should be added at the top level of the workflow file (after thename
andon
keys), so it applies to all jobs unless overridden. No changes to the jobs themselves are necessary unless a job requires additional permissions.