debug: add OIDC detection debug step (#27) #14
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 }}" |