feat: autopublish to npm registry in GH #12
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: Publish to GitHub Packages | |
| on: | |
| # Trigger on pull requests (for testing/validation) - only from same repo | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| # Trigger on pushes to main branch | |
| push: | |
| branches: | |
| - main | |
| # Allow manual triggering | |
| workflow_dispatch: | |
| env: | |
| NODE_VERSION: lts/jod | |
| REGISTRY: npm.pkg.github.com | |
| # Use the repository owner as the scope | |
| SCOPE: '@cowprotocol' | |
| permissions: | |
| contents: read | |
| packages: write | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| publish: | |
| name: Publish to GitHub Packages | |
| runs-on: ubuntu-latest | |
| # Security: Only run on internal PRs, main branch pushes, or external PRs with explicit approval | |
| if: github.event_name == 'push' || (github.event_name == 'pull_request' && (github.event.pull_request.head.repo.full_name == github.repository || contains(github.event.pull_request.labels.*.name, 'allow-publish'))) | |
| steps: | |
| - name: Security Check | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "π Checking PR security..." | |
| echo "PR from: ${{ github.event.pull_request.head.repo.full_name }}" | |
| echo "Target repo: ${{ github.repository }}" | |
| # Check if it's an internal PR | |
| if [ "${{ github.event.pull_request.head.repo.full_name }}" = "${{ github.repository }}" ]; then | |
| echo "β Internal PR - proceeding with publish" | |
| else | |
| # Check for allow-publish label | |
| echo "π Checking for 'allow-publish' label..." | |
| if echo "${{ toJson(github.event.pull_request.labels) }}" | grep -q '"name":"allow-publish"'; then | |
| echo "β External PR with 'allow-publish' label - proceeding with publish" | |
| else | |
| echo "β External PR without 'allow-publish' label - skipping publish for security" | |
| echo "π‘ To enable publishing for this external PR, add the 'allow-publish' label" | |
| exit 1 | |
| fi | |
| fi | |
| else | |
| echo "β Push to main branch - proceeding with publish" | |
| fi | |
| - name: Cancel Previous Runs | |
| uses: styfle/[email protected] | |
| with: | |
| access_token: ${{ github.token }} | |
| - name: Remove broken apt repos [Ubuntu] | |
| run: | | |
| for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| scope: ${{ env.SCOPE }} | |
| always-auth: true | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10.8.0 | |
| - name: Cache pnpm store | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.pnpm-store | |
| key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Generate code | |
| run: pnpm codegen | |
| - name: Build packages | |
| run: pnpm build | |
| # - name: Run tests | |
| # run: pnpm test | |
| # - name: Run linting | |
| # run: pnpm lint | |
| - name: Configure npm for GitHub Packages | |
| run: | | |
| # Override registry for @cowprotocol scope to use GitHub Packages | |
| echo "@cowprotocol:registry=https://${{ env.REGISTRY }}" >> ~/.npmrc | |
| # Always authenticate | |
| echo "always-auth=true" >> ~/.npmrc | |
| # Set auth token | |
| echo "//${{ env.REGISTRY }}/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> ~/.npmrc | |
| # Keep default registry as npmjs.org for other packages | |
| echo "registry=https://registry.npmjs.org/" >> ~/.npmrc | |
| - name: Determine version strategy | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| # For PRs, use a pre-release version with PR number | |
| VERSION_SUFFIX="pr-${{ github.event.number }}" | |
| echo "version_suffix=$VERSION_SUFFIX" >> $GITHUB_OUTPUT | |
| echo "tag=pr" >> $GITHUB_OUTPUT | |
| echo "is_pr=true" >> $GITHUB_OUTPUT | |
| else | |
| # For main branch, use latest tag | |
| echo "version_suffix=" >> $GITHUB_OUTPUT | |
| echo "tag=latest" >> $GITHUB_OUTPUT | |
| echo "is_pr=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Create pre-release versions for PRs | |
| if: steps.version.outputs.is_pr == 'true' | |
| run: | | |
| # Create pre-release versions for all packages | |
| find packages -name "package.json" -exec sh -c ' | |
| for file; do | |
| echo "Creating pre-release version for $file" | |
| # Use npm version to create pre-release version | |
| cd "$(dirname "$file")" | |
| npm version prerelease --preid="${{ steps.version.outputs.version_suffix }}" --no-git-tag-version | |
| cd - > /dev/null | |
| done | |
| ' _ {} \; | |
| - name: Debug auth (whoami) | |
| run: npm whoami --registry=https://npm.pkg.github.com | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Debug ping | |
| run: npm ping --registry=https://npm.pkg.github.com | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish packages to GitHub Packages | |
| run: | | |
| # Publish all packages | |
| pnpm publish -r --filter="./packages/**" --tag ${{ steps.version.outputs.tag }} --no-git-checks | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Restore original versions (PR only) | |
| if: steps.version.outputs.is_pr == 'true' | |
| run: | | |
| # Restore original package.json versions | |
| git checkout -- packages/*/package.json | |
| - name: Create PR comment with package info | |
| if: steps.version.outputs.is_pr == 'true' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const packages = [ | |
| '@cowprotocol/cow-sdk', | |
| '@cowprotocol/sdk-trading', | |
| '@cowprotocol/sdk-bridging', | |
| '@cowprotocol/sdk-common', | |
| '@cowprotocol/sdk-config', | |
| '@cowprotocol/sdk-contracts-ts', | |
| '@cowprotocol/sdk-order-book', | |
| '@cowprotocol/sdk-order-signing', | |
| '@cowprotocol/sdk-cow-shed', | |
| '@cowprotocol/sdk-composable', | |
| '@cowprotocol/sdk-weiroll', | |
| '@cowprotocol/sdk-subgraph', | |
| '@cowprotocol/sdk-app-data' | |
| ]; | |
| const prVersion = '${{ steps.version.outputs.version_suffix }}'; | |
| const isExternalPR = '${{ github.event.pull_request.head.repo.full_name }}' !== '${{ github.repository }}'; | |
| const comment = `## π¦ GitHub Packages Published | |
| The following packages have been published to GitHub Packages with pre-release version \`${prVersion}\`: | |
| ${packages.map(pkg => `- \`${pkg}@*-${prVersion}\``).join('\n')} | |
| ${isExternalPR ? '> **Note:** This is an external PR with the \`allow-publish\` label enabled.' : ''} | |
| ### Installation | |
| To install these packages, configure npm to use GitHub Packages: | |
| \`\`\`bash | |
| npm config set @cowprotocol:registry https://npm.pkg.github.com | |
| npm config set //npm.pkg.github.com/:_authToken YOUR_GITHUB_TOKEN | |
| \`\`\` | |
| Then install with: | |
| \`\`\`bash | |
| npm install @cowprotocol/cow-sdk@*-${prVersion} | |
| \`\`\` | |
| ### View Packages | |
| You can view the published packages at: https://github.com/cowprotocol/cow-sdk/packages`; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: comment | |
| }); |