cloudflare / wrangler-action

🧙‍♀️ easily deploy cloudflare workers applications using wrangler and github actions
Apache License 2.0
1.25k stars 159 forks source link

[Bug] Wrangler-action cannot detect alternative package managers when using a non-root workingDirectory #198

Closed AdiRishi closed 10 months ago

AdiRishi commented 1 year ago

Versions/tools

Steps to reproduce

Expected outcome

Actual outcome

Run cloudflare/wrangler-action@v3.3.1
  with:
    accountId: ***
    apiToken: ***
    workingDirectory: workers/apex-gateway
    command: deploy
    quiet: false
  env:
    TURBO_TOKEN: ***
    TURBO_REMOTE_CACHE_SIGNATURE_KEY: ***
    TURBO_TEAM: team_tiptop
    TURBO_API: ***
    GITHUB_SHA: ***
    CLOUDFLARE_ACCOUNT_ID: ***
    CLOUDFLARE_API_TOKEN: ***
    NODE_ENV: production
    PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
📥 Installing Wrangler
  Running command: npm i wrangler@3.5.1
  npm ERR! code EUNSUPPORTEDPROTOCOL
  Error: Command failed: npm i wrangler@3.5.1
  npm ERR! code EUNSUPPORTEDPROTOCOL
  npm ERR! Unsupported URL Type "workspace:": workspace:*

  npm ERR! A complete log of this run can be found in: /home/runner/.npm/_logs/2023-10-14T09_39_26_137Z-debug-0.log

  npm ERR! Unsupported URL Type "workspace:": workspace:*

  npm ERR! A complete log of this run can be found in: /home/runner/.npm/_logs/2023-10-14T09_39_26_137Z-debug-0.log
  Error: 🚨 Action failed

Investigation/explanation

Looking into the codebase we can see that src/packageManagers.ts has the detectPackageManager function. This function clearly searches for the relevant *.lock file within the provided workingDirectory

function detectPackageManager(
    workingDirectory = ".",
): PackageManagerValue | null {
    if (existsSync(path.join(workingDirectory, "package-lock.json"))) {
        return "npm";
    }
    if (existsSync(path.join(workingDirectory, "yarn.lock"))) {
        return "yarn";
    }
    if (existsSync(path.join(workingDirectory, "pnpm-lock.yaml"))) {
        return "pnpm";
    }
    if (existsSync(path.join(workingDirectory, "bun.lockb"))) {
        return "bun";
    }
    return null;
}

This approach won't work in the monorepo / subfolder workingDirectory scenario since the *.lock files are typically in the root of the project.

AdiRishi commented 1 year ago

Just wanted to add some further detail. @enfipy you mentioned in the other issue that using packageManager: 'pnpm' fixed this issue for you.

I just tried this, however from what I can tell this doesn't fix the problem. Here is the definition and output for me

- name: Deploy apex-gateway
  uses: cloudflare/wrangler-action@v3.3.1
  with:
    accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
    apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
    workingDirectory: 'workers/apex-gateway'
    packageManager: 'pnpm'
    command: 'deploy'

Output

Run cloudflare/wrangler-action@v3.3.1
  with:
    accountId: ***
    apiToken: ***
    workingDirectory: workers/apex-gateway
    packageManager: pnpm
    command: deploy
    quiet: false
  env:
    CLOUDFLARE_ACCOUNT_ID: ***
    CLOUDFLARE_API_TOKEN: ***
    NODE_ENV: production
    PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
📥 Installing Wrangler
  Running command: pnpm add wrangler@3.5.1
  Error: Command failed: pnpm add wrangler@3.5.1
  Error: 🚨 Action failed

As a side note, I also tried passing wranglerVersion: '3.13.1' to the github action. Didn't work

  Running command: pnpm add wrangler@3.13.1
  Error: Command failed: pnpm add wrangler@3.13.1
  Error: 🚨 Action failed

I also want to point out that logging the underlying error would be very helpful, since right now it's a black box.

enfipy commented 1 year ago

@AdiRishi Yes, you are correct. There are actually two issues as Cina Saffary mentioned after my comment.

To be honest, I don't really know why exactly you are seeing this issue. Have you tried to put wranglerVersion: "3.13.1 -w" too? Perhaps the problem is in the lack of a workspace flag for pnpm.

Because in my current setup, all I have is the installed devDependencies: { "wrangler": "3.13.1" } in ./apps/api/ and the following configuration in CI:

- uses: pnpm/action-setup@v2
  with:
    version: 8
- uses: cloudflare/wrangler-action@v3
  with:
    apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
    workingDirectory: ./apps/api/
    environment: staging
    packageManager: pnpm

That results in this:

📥 Installing Wrangler
  Running command: pnpm add wrangler@3.5.1
  ✅ Wrangler installed
🚀 Running Wrangler Commands
  🚀 Executing command: pnpm exec wrangler deploy --env staging
   ⛅️ wrangler 3.5.1 (update available 3.13.1)
maxpetretta commented 1 year ago

I'm seeing an additional strange behavior. When passing any value but NODE_ENV: development, the action-specific wrangler installation fails:

# Install succeeds
  - name: Deploy Cloudflare Worker
    uses: cloudflare/wrangler-action@v3
    with:
      apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
      workingDirectory: packages/backend
      wranglerVersion: "3"
      packageManager: pnpm
      secrets: |
        NODE_ENV
        DATABASE_URL
    env:
      NODE_ENV: development
      DATABASE_URL: ${{ secrets.DATABASE_URL }}

# Install fails
  - name: Deploy Cloudflare Worker
    uses: cloudflare/wrangler-action@v3
    # Same as above, but...
    env:
      NODE_ENV: production
      DATABASE_URL: ${{ secrets.DATABASE_URL }}

Solution is to manage NODE_ENV in wranger.toml, and to specify the environment: production variable on the action:

# Install succeeds
  - name: Deploy Cloudflare Worker
    uses: cloudflare/wrangler-action@v3
    with:
      apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
      workingDirectory: packages/backend
      wranglerVersion: "3"
      packageManager: pnpm
      environment: production
      secrets: |
        DATABASE_URL
    env:
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
AdiRishi commented 10 months ago

Hey all, I finally got around to trying again today, and @enfipy was correct, the action works when you configure it properly. Given that I opened this issue, I'm going to close it, as the use case I mentioned in the issue description is no longer valid.

For anyone else who comes across this, here is the fully working workflow file I used in GitHub.

name: Deploy Cloudflare Pages

on:
  workflow_run:
    workflows: ['CI']
    types: [completed]
    branches: [main]

jobs:
  check:
    name: Build and deploy CF Pages
    runs-on: ubuntu-latest
    if: github.event.workflow_run.conclusion == 'success'
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v2
        with:
          version: 8

      - uses: actions/setup-node@v4
        with:
          node-version-file: '.nvmrc'
          cache: 'pnpm'

      - run: pnpm install
      - run: pnpm build

      - name: Deploy arishi-website-webapp
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          command: pages deploy public/ --project-name=adishwar-rishi-website
          workingDirectory: 'apps/arishi-website-webapp'
          packageManager: 'pnpm'
          wranglerVersion: '3.23.0'