Skip to content

debug: add OIDC detection debug step (#27) #14

debug: add OIDC detection debug step (#27)

debug: add OIDC detection debug step (#27) #14

Workflow file for this run

name: Production Release
"on":
push:
tags:
- "v*.*.*"
jobs:
validate:
name: Validate Code and GSD Compliance
uses: ./.github/workflows/validate.yml
with:
working_directory: "./gsd-opencode"
update_version:
name: Update Package Version from Tag
runs-on: ubuntu-latest
needs: validate
outputs:
version: ${{ steps.extract_version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version from tag and update package.json
id: extract_version
working-directory: ./gsd-opencode
run: |
echo "Extracting version from tag: ${{ github.ref_name }}"
# Extract version from git tag (remove 'v' prefix)
TAG_VERSION="${{ github.ref_name }}"
VERSION=${TAG_VERSION#v}
echo "Extracted version: $VERSION"
# Update package.json with the tag version
npm version "$VERSION" --no-git-tag-version --allow-same-version
# Verify the update
UPDATED_VERSION=$(node -p "require('./package.json').version")
echo "Updated package.json version to: $UPDATED_VERSION"
# Output for subsequent jobs
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Package version updated to match tag"
- name: Update package name for npmjs.org
working-directory: ./gsd-opencode
run: |
echo "Updating package name for npmjs.org..."
npm pkg set name=gsd-opencode
UPDATED_NAME=$(node -p "require('./package.json').name")
echo "✓ Package name updated to: $UPDATED_NAME"
- name: Upload updated package.json
uses: actions/upload-artifact@v4
with:
name: updated-package-json
path: ./gsd-opencode/package.json
retention-days: 1
comprehensive_test:
name: Run Production Tests
runs-on: ubuntu-latest
needs: [validate, update_version]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download updated package.json
uses: actions/download-artifact@v4
with:
name: updated-package-json
path: ./gsd-opencode
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
cache: "npm"
cache-dependency-path: "gsd-opencode/package.json"
- name: Install dependencies
working-directory: ./gsd-opencode
run: npm install
- name: Full security audit
working-directory: ./gsd-opencode
run: |
echo "Running full security audit for production..."
npm audit --audit-level=moderate
echo "✓ Security audit completed"
- name: Production readiness checks
working-directory: ./gsd-opencode
run: |
echo "Running production readiness checks..."
# Use version from update_version job
VERSION="${{ needs.update_version.outputs.version }}"
echo "Expected version from tag: $VERSION"
# Validate current package version
CURRENT_VERSION=$(node -p "require('./package.json').version")
echo "Current package version: $CURRENT_VERSION"
if [ "$CURRENT_VERSION" != "$VERSION" ]; then
echo "❌ Package version ($CURRENT_VERSION) does not match expected version ($VERSION)"
exit 1
fi
echo "✓ Version validation passed"
# Check package.json fields
node -e "
const pkg = JSON.parse(require('fs').readFileSync('package.json', 'utf8'));
const required = ['name', 'version', 'description', 'license', 'author', 'repository'];
for (const field of required) {
if (!pkg[field]) {
console.error('❌ Missing required field in package.json:', field);
process.exit(1);
}
}
console.log('✓ All required package.json fields present');
"
echo "✓ Production readiness checks completed"
- name: Archive production test results
if: always()
uses: actions/upload-artifact@v4
with:
name: production-test-results-${{ github.run_number }}
path: |
gsd-opencode/package-lock.json
gsd-opencode/npm-audit-report.json 2>/dev/null || true
retention-days: 90
build_production:
name: Build Production Release
runs-on: ubuntu-latest
needs: [validate, update_version, comprehensive_test]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for changelog generation
- name: Download updated package.json
uses: actions/download-artifact@v4
with:
name: updated-package-json
path: ./gsd-opencode
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
cache: "npm"
cache-dependency-path: "gsd-opencode/package.json"
- name: Install dependencies
working-directory: ./gsd-opencode
run: npm install
- name: Build production artifacts
working-directory: ./gsd-opencode
run: |
echo "Building production artifacts..."
# Create production build directory
mkdir -p dist
# Copy essential files
cp -r bin dist/
cp -r command dist/
cp -r get-shit-done dist/
cp package.json dist/
cp README.md dist/ 2>/dev/null || echo "README.md not found, creating basic one"
cp LICENSE dist/ 2>/dev/null || echo "LICENSE not found, skipping"
# Create production README if not exists
if [ ! -f "dist/README.md" ]; then
cat > dist/README.md << 'EOF'
# gsd-opencode
A meta-prompting, context engineering and spec-driven development system for OpenCode by TÂCHES.
## Installation
```bash
npm install -g gsd-opencode
```
## Usage
```bash
gsd-opencode --help
```
## License
MIT
EOF
fi
# Create version info
VERSION="${{ needs.update_version.outputs.version }}"
echo "Building version: $VERSION"
cat > dist/VERSION << EOF
Version: $VERSION
Commit: ${{ github.sha }}
Build Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
EOF
# Build npm package
npm pack
echo "✓ Production build completed"
- name: Generate changelog
working-directory: ./gsd-opencode
run: |
echo "Generating changelog..."
# Get previous tag
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
CURRENT_TAG="v${{ needs.update_version.outputs.version }}"
if [ -n "$PREVIOUS_TAG" ]; then
echo "Generating changelog from $PREVIOUS_TAG to $CURRENT_TAG..."
git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..$CURRENT_TAG > CHANGELOG.md
echo "## Changes since $PREVIOUS_TAG" >> CHANGELOG.md
echo "" >> CHANGELOG.md
git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..$CURRENT_TAG >> CHANGELOG.md
else
echo "No previous tag found, generating full changelog..."
echo "## Release $CURRENT_TAG" > CHANGELOG.md
echo "" >> CHANGELOG.md
git log --pretty=format:"- %s (%h)" >> CHANGELOG.md
fi
echo "✓ Changelog generated"
- name: Generate checksums
working-directory: ./gsd-opencode
run: |
echo "Generating SHA256 checksums..."
# Generate checksum for npm tarball
tarball=$(ls gsd-opencode-*.tgz)
sha256sum "$tarball" > "$tarball.sha256"
# Generate checksum for distribution
cd dist
find . -type f -exec sha256sum {} + | sort > ../dist-checksums.sha256
cd ..
# Create signed checksums file
cat > release-checksums.txt << EOF
gsd-opencode Release Checksums
==============================
Version: v${{ needs.update_version.outputs.version }}
Commit: ${{ github.sha }}
Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
NPM Package:
$(sha256sum "$tarball")
Distribution Files:
$(cat dist-checksums.sha256)
EOF
echo "✓ Checksums generated"
- name: Create release metadata
working-directory: ./gsd-opencode
run: |
echo "Creating release metadata..."
cat > release-metadata.json << EOF
{
"release_id": "${{ github.run_number }}",
"tag": "v${{ needs.update_version.outputs.version }}",
"commit_sha": "${{ github.sha }}",
"release_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"version": "$(node -p "require('./package.json').version")",
"node_version": "$(node --version)",
"platform": "ubuntu-latest",
"trigger": "push_tag",
"workflow": "release",
"is_prerelease": false,
"artifacts": [
"gsd-opencode-v${{ needs.update_version.outputs.version }}.tgz",
"gsd-opencode-v${{ needs.update_version.outputs.version }}.tgz.sha256",
"dist-checksums.sha256",
"release-checksums.txt",
"CHANGELOG.md"
]
}
EOF
echo "✓ Release metadata created"
- name: Upload release artifacts
uses: actions/upload-artifact@v4
with:
name: gsd-opencode-release-v${{ needs.update_version.outputs.version }}
path: |
gsd-opencode/dist/
gsd-opencode/gsd-opencode-*.tgz
gsd-opencode/gsd-opencode-*.tgz.sha256
gsd-opencode/dist-checksums.sha256
gsd-opencode/release-checksums.txt
gsd-opencode/CHANGELOG.md
gsd-opencode/release-metadata.json
retention-days: 365
create_release:
name: Release to GH and NPM
runs-on: ubuntu-latest
needs: [validate, update_version, comprehensive_test, build_production]
permissions:
contents: write
id-token: write
env:
GH_TOKEN: ${{ github.token }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: gsd-opencode-release-v${{ needs.update_version.outputs.version }}
path: ./release-artifacts
- name: Prepare release notes
run: |
echo "Preparing release notes..."
VERSION="v${{ needs.update_version.outputs.version }}"
# Create release notes
cat > release-notes.md << EOF
# gsd-opencode $VERSION
Automated release from commit ${{ github.sha }}.
## Installation
npm install -g gsd-opencode@$VERSION
## Download
Choose the asset that matches your needs:
- gsd-opencode-$VERSION.tgz - NPM package for manual installation
- gsd-opencode-$VERSION.tgz.sha256 - SHA256 checksum for NPM package
- release-checksums.txt - Complete checksums for all files
## Verification
Verify the integrity of downloaded files using the provided SHA256 checksums.
---
EOF
# Add changelog if available
if [ -f "./release-artifacts/CHANGELOG.md" ]; then
echo "" >> release-notes.md
echo "## Changelog" >> release-notes.md
echo "" >> release-notes.md
cat ./release-artifacts/CHANGELOG.md >> release-notes.md
fi
echo "✓ Release notes prepared"
- name: Create GitHub Release
run: |
echo "Creating GitHub release for v${{ needs.update_version.outputs.version }}..."
# Check if release already exists
if gh release view "v${{ needs.update_version.outputs.version }}" &>/dev/null; then
echo "Release v${{ needs.update_version.outputs.version }} already exists, updating..."
# Update existing release
gh release edit "v${{ needs.update_version.outputs.version }}" \
--title "gsd-opencode v${{ needs.update_version.outputs.version }}" \
--notes-file release-notes.md \
--latest
else
# Create new release
gh release create "v${{ needs.update_version.outputs.version }}" \
--title "gsd-opencode v${{ needs.update_version.outputs.version }}" \
--notes-file release-notes.md \
--latest
fi
echo "✓ GitHub release updated/created"
- name: Upload release assets
run: |
echo "Uploading release assets..."
# Upload all artifacts
for asset in ./release-artifacts/*; do
if [ -f "$asset" ]; then
echo "Uploading $(basename "$asset")"
gh release upload "v${{ needs.update_version.outputs.version }}" "$asset"
fi
done
echo "✓ All release assets uploaded"
- name: Setup Node.js for OIDC
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Debug OIDC setup
run: |
echo "=== OIDC Debug Info ==="
echo "npm version: $(npm --version)"
echo "node version: $(node --version)"
echo ""
echo "=== Environment Variables ==="
env | grep -i oidc || echo "No OIDC env vars found"
env | grep -i token || echo "No TOKEN env vars found"
echo ""
echo "=== npm config ==="
npm config list
echo ""
echo "=== npm whoami ==="
npm whoami || echo "npm whoami failed - this is expected if OIDC not working"
- name: Publish to npm
if: startsWith(github.ref, 'refs/tags/v')
run: |
echo "Publishing production release to npm using OIDC..."
cd ./release-artifacts
# Find the tarball
TARBALL=$(ls gsd-opencode-*.tgz)
# Extract package.json from tarball to get package name
tar -xzf "$TARBALL" package/package.json --strip-components=1
PACKAGE_NAME=$(node -p "JSON.parse(require('fs').readFileSync('package.json', 'utf8')).name")
rm package.json
VERSION="${{ needs.update_version.outputs.version }}"
echo "Publishing $TARBALL as $PACKAGE_NAME@$VERSION to npm using OIDC token"
# Publish to npm using OIDC token (latest tag by default)
npm publish "$TARBALL" --access public
echo "✓ Published production release to npm successfully using OIDC"
echo "📦 Package: $PACKAGE_NAME@$VERSION"
echo "🔗 Install with: npm install -g $PACKAGE_NAME@$VERSION"
echo "🌐 NPM page: https://www.npmjs.com/package/$PACKAGE_NAME"
- name: Update latest tag
run: |
echo "Updating latest tag..."
# Remove existing latest tag if it exists
git tag -d latest 2>/dev/null || true
git push origin :latest 2>/dev/null || true
# Create and push new latest tag
git tag latest ${{ github.sha }}
git push origin latest
echo "✓ Latest tag updated"
notify:
name: Send Release Notifications
runs-on: ubuntu-latest
needs:
[
validate,
update_version,
comprehensive_test,
build_production,
create_release,
]
if: always()
steps:
- name: Release notification summary
run: |
echo "## Production Release Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Release:** v${{ needs.update_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "**Date:** $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Job status
echo "### Job Status" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Validate | ${{ needs.validate.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Update Version | ${{ needs.update_version.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Production Test | ${{ needs.comprehensive_test.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Build Production | ${{ needs.build_production.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Create Release | ${{ needs.create_release.result }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Overall status
if [[ "${{ needs.validate.result }}" == "success" && "${{ needs.update_version.result }}" == "success" && "${{ needs.comprehensive_test.result }}" == "success" && "${{ needs.build_production.result }}" == "success" && "${{ needs.create_release.result }}" == "success" ]]; then
echo "🎉 **Release Status: SUCCESS**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Production release v${{ needs.update_version.outputs.version }} completed successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Release Page:** [v${{ needs.update_version.outputs.version }}](https://github.com/${{ github.repository }}/releases/tag/v${{ needs.update_version.outputs.version }})" >> $GITHUB_STEP_SUMMARY
echo "**NPM Package:** \`npm install -g gsd-opencode@v${{ needs.update_version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Release Status: FAILED**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "One or more release jobs failed. Check the job logs for details." >> $GITHUB_STEP_SUMMARY
echo "**Actions Run:** [View Logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
fi
- name: Notify on release failure
if: needs.validate.result == 'failure' || needs.update_version.result == 'failure' || needs.comprehensive_test.result == 'failure' || needs.build_production.result == 'failure' || needs.create_release.result == 'failure'
run: |
echo "❌ Production release failed!"
echo "Release: v${{ needs.update_version.outputs.version }}"
echo "Commit: ${{ github.sha }}"
echo "Check the logs for details: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
exit 1
- name: Release success notification
if: needs.validate.result == 'success' && needs.update_version.result == 'success' && needs.comprehensive_test.result == 'success' && needs.build_production.result == 'success' && needs.create_release.result == 'success'
run: |
echo "🚀 Production release v${{ needs.update_version.outputs.version }} completed successfully!"
echo ""
echo "Release page: https://github.com/${{ github.repository }}/releases/tag/v${{ needs.update_version.outputs.version }}"
echo "Install with: npm install -g gsd-opencode@v${{ needs.update_version.outputs.version }}"