Couldn't find a package.json file when setting up Github actions for Firebase Hosting

Viewed 2401

When initializing github actions for firebase hosting i specified the following:

Set up the workflow to run a build script before every deploy? Yes What script should be run before every deploy? yarn run build.

This workflow gives me the error

Run yarn run build
yarn run v1.22.10
error Couldn't find a package.json file in "/home/runner/work/SpaceBar/SpaceBar"
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Process completed with exit code 1.

I have a package.json file in my project directory. Why is it saying that it cannot find it?

firebase-hosting-merge.yml is in the directory called spacebar, which contains another directory called spacebar containing the package.json file. Is there anyway to cd into the sub directory in this file

name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: yarn run build
      - uses: FirebaseExtended/action-hosting-deploy@v0
2 Answers

As the actions/checkout action gave you access to the repository files and directories, you can just cd into the directory where the package.json file is located before executing the yarn command. Otherwise, it will only look for it at the repository root.

Example (for your second step)

run: |
   cd spacebar/spacebar
   yarn run build

I had the same error with a similar setup. Unfortunately though, the answer marked as accepted did not solve my problem.

However, after lots and lots of googling, I did manage to solve my problem and just wanna share what I found in case anybody else is still having issues like I had:

As GuiFalourd correctly mentioned, the error is asking you to be in the directory where your package.json file is located. But as it turns out, there are multiple ways of doing this - some more correct than others. In my specific case, the action I'm using and all of the commands running in it are meant to be run in a specific directory and so I chose to declare the directory with the keyword working-directory in the defaults setting:

name: Build & deploy

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./frontend
    
    strategy:
      matrix:
        node-version: [12.x]
steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
        
    - name: Clean Cache
      run: |
        npm cache clean --force
    - name: CI Install
      run: |
        npm ci
    - name: NPM Install
      run: |
        npm install      
    - name: Production Build
      run: |
        npm run build
      env:
        CI: false
    - name: Unit Tests
      run: |
        npm run test --passWithNoTests

The other working alternative would have been to set the working-directory in every step with a command. This can be useful if you want to run a specific command in a specific directory once, while everything else is run somewhere else. Downside is it looks messy and is redundant if everything is meant to be run in the same directory anyway:

name: Build & deploy

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [12.x]
        
    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
        
    - name: Clean Cache
      working-directory: ./frontend
      run: |
        npm cache clean --force
    - name: CI Install
      working-directory: ./frontend
      run: |
        npm ci
    - name: NPM Install
      working-directory: ./frontend
      run: |
        npm install      
    - name: Production Build
      working-directory: ./frontend
      run: |
        npm run build
      env:
        CI: false
    - name: Unit Tests
      working-directory: ./frontend
      run: |
        npm run test --passWithNoTests

DO NOTE: The working-directory keyword does not work for the uses and with keywords. Depending on what deploy action you're using, you will have to set this in its own env settings.

In my case, my final YML file looks like this:

name: Build & deploy

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./frontend
    
    strategy:
      matrix:
        node-version: [12.x]
        
    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
        
    - name: Clean Cache
      run: |
        npm cache clean --force
    - name: CI Install
      run: |
        npm ci
    - name: NPM Install
      run: |
        npm install      
    - name: Production Build
      run: |
        npm run build
      env:
        CI: false
    - name: Unit Tests
      run: |
         npm run test --passWithNoTests
    - name: Deploy to S3
      uses: jakejarvis/s3-sync-action@master
      with:
        args: --acl public-read --delete
      env:
        AWS_S3_BUCKET: ${{ secrets.AWS_PRODUCTION_BUCKET_NAME }}
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS_REGION: ${{ secrets.AWS_REGION }}
        SOURCE_DIR: "./frontend/build"

Hope this helps.

Related