Repository: nuxt/create-nuxt-app
Pull request #621 (2020-09-30 20:12:32)

feat: add GitHub Action out-of-the-box
- [x] Enables GitHub actions CI workflow out of the box
	- [x] If user selects one of the test runners, `yarn|npm run test` will be added to `.github/workflows/ci.yml`
	- [x] If user selects one of the linting options, `yarn|npm run lint` will be added to `.github/workflows/ci.yml`
- [x] If `github-actions` option is selected from CI (while scaffolding new nuxt app), `dependabot` config is auto-updated to support the `github-actions` ecosystem
- [x] Debug why tests are failing (commitlint option in answers.linters)

vinayakkulkarni: We could even add Circle CI, Travis CI etc. in future! 

Patch:
diff --git a/README.md b/README.md
index 012d3b2..ee675d3 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,8 @@ yarn create nuxt-app <my-project>
     - [jsconfig.json](https://code.visualstudio.com/docs/languages/jsconfig)
     - [Semantic PR](https://probot.github.io/apps/semantic-pull-requests/)
     - [Dependabot (for GitHub only)](https://dependabot.com/)
+1. Continous Integration
+    - [GitHub Actions](https://github.com/features/actions)
 
 ## CLI Options
 
diff --git a/packages/cna-template/template/dependabot.yml b/packages/cna-template/template/dependabot.yml
index 3f18b0f..a6ecab2 100644
--- a/packages/cna-template/template/dependabot.yml
+++ b/packages/cna-template/template/dependabot.yml
@@ -1,18 +1,34 @@
 version: 2
 updates:
+# Fetch and update latest `npm` packages
 - package-ecosystem: npm
-  directory: "/"
+  directory: '/'
   schedule:
     interval: daily
     time: '00:00'
-  open-pull-requests-limit: 99
+  open-pull-requests-limit: 10
   reviewers:
     - <%= gitUsername %>
   assignees:
     - <%= gitUsername %>
-  labels:
-    - dependencies
   commit-message:
     prefix: fix
     prefix-development: chore
     include: scope
+<%_ if (ci === 'github-actions') { _%>
+# Fetch and update latest `github-actions` pkgs
+- package-ecosystem: github-actions
+  directory: '/'
+  schedule:
+    interval: daily
+    time: '00:00'
+  open-pull-requests-limit: 10
+  reviewers:
+    - <%= gitUsername %>
+  assignees:
+    - <%= gitUsername %>
+  commit-message:
+    prefix: fix
+    prefix-development: chore
+    include: scope
+<%_ } _%>
diff --git a/packages/cna-template/template/frameworks/github-actions/.github/workflows/ci.yml b/packages/cna-template/template/frameworks/github-actions/.github/workflows/ci.yml
new file mode 100644
index 0000000..3bb9016
--- /dev/null
+++ b/packages/cna-template/template/frameworks/github-actions/.github/workflows/ci.yml
@@ -0,0 +1,66 @@
+name: ci
+
+on:
+  push:
+    branches:
+      - main
+      - master
+  pull_request:
+    branches:
+      - main
+      - master
+
+jobs:
+  ci:
+    runs-on: ${{ matrix.os }}
+
+    strategy:
+      matrix:
+        os: [ubuntu-latest]
+        node: [14]
+
+    steps:
+      - name: Checkout 🛎
+        uses: actions/checkout@master
+
+      - name: Setup node env 🏗
+        uses: actions/setup-node@v2.1.2
+        with:
+          node-version: ${{ matrix.node }}
+
+      <%_ if (pm === 'yarn') { _%>
+      - name: Get yarn cache directory path 🛠
+        id: yarn-cache-dir-path
+        run: echo "::set-output name=dir::$(yarn cache dir)"
+
+      - name: Cache node_modules 📦
+        uses: actions/cache@v2
+        id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
+        with:
+          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+          restore-keys: |
+            ${{ runner.os }}-yarn-
+      <%_ } _%>
+      <%_ if (pm === 'npm') { _%>
+      - name: Cache node_modules 📦
+        uses: actions/cache@v2
+        with:
+          path: ~/.npm
+          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+          restore-keys: |
+            ${{ runner.os }}-node-
+      <%_ } _%>
+
+      - name: Install dependencies 👨🏻‍💻
+        run: <%= pmRun === 'yarn' ? 'yarn' : 'npm ci' %>
+
+      <%_ if (linter.length > 0) { _%>
+      - name: Run linter 👀
+        run: <%= pmRun  %> lint
+      <%_ } _%>
+
+      <%_ if (test !== 'none') { _%>
+      - name: Run tests 🧪
+        run: <%= pmRun  %> test
+      <%_ } _%>
diff --git a/packages/create-nuxt-app/lib/prompts.js b/packages/create-nuxt-app/lib/prompts.js
index dee3c51..4dccde5 100644
--- a/packages/create-nuxt-app/lib/prompts.js
+++ b/packages/create-nuxt-app/lib/prompts.js
@@ -116,7 +116,18 @@ module.exports = [
     default: []
   },
   {
-    when: answers => answers.devTools.includes('dependabot'),
+    when: ({ test, linter }) => test !== 'none' || linter.length > 0,
+    name: 'ci',
+    message: 'Continuous integration:',
+    type: 'list',
+    choices: [
+      { name: 'None', value: 'none' },
+      { name: 'GitHub Actions (GitHub only)', value: 'github-actions' }
+    ],
+    default: 'none'
+  },
+  {
+    when: ({ devTools, ci }) => devTools.includes('dependabot') || ci !== 'none',
     name: 'gitUsername',
     message: 'What is your GitHub username?',
     default: '{gitUser.name}',
diff --git a/packages/create-nuxt-app/lib/saofile.js b/packages/create-nuxt-app/lib/saofile.js
index 17c18d7..af2f176 100644
--- a/packages/create-nuxt-app/lib/saofile.js
+++ b/packages/create-nuxt-app/lib/saofile.js
@@ -76,6 +76,14 @@ module.exports = {
       })
     }
 
+    if (this.answers.ci && this.answers.ci !== 'none') {
+      actions.push({
+        type: 'add',
+        files: '**',
+        templateDir: join(frameworksDir, this.answers.ci)
+      })
+    }
+
     actions.push({
       type: 'add',
       files: '*',


Test patch:
diff --git a/packages/create-nuxt-app/test/snapshots/index.test.js.md b/packages/create-nuxt-app/test/snapshots/index.test.js.md
index b3de715..f7c7e64 100644
--- a/packages/create-nuxt-app/test/snapshots/index.test.js.md
+++ b/packages/create-nuxt-app/test/snapshots/index.test.js.md
@@ -4,6 +4,170 @@ The actual snapshot is saved in `index.test.js.snap`.
 
 Generated by [AVA](https://avajs.dev).
 
+## verify ci: GitHub Actions (GitHub only)
+
+> Generated files
+
+    [
+      '.editorconfig',
+      '.gitignore',
+      'README.md',
+      'assets/README.md',
+      'components/Logo.vue',
+      'components/README.md',
+      'layouts/README.md',
+      'layouts/default.vue',
+      'middleware/README.md',
+      'nuxt.config.js',
+      'package.json',
+      'pages/README.md',
+      'pages/index.vue',
+      'plugins/README.md',
+      'static/README.md',
+      'static/favicon.ico',
+      'store/README.md',
+    ]
+
+> package.json
+
+    {
+      dependencies: {
+        'core-js': '^3.6.5',
+        nuxt: '^2.14.6',
+      },
+      devDependencies: {},
+      private: true,
+      scripts: {
+        build: 'nuxt build',
+        dev: 'nuxt',
+        generate: 'nuxt generate',
+        start: 'nuxt start',
+      },
+    }
+
+> Generated nuxt.config.js
+
+    `export default {␊
+      // Global page headers (https://go.nuxtjs.dev/config-head)␊
+      head: {␊
+        title: 'output',␊
+        meta: [␊
+          { charset: 'utf-8' },␊
+          { name: 'viewport', content: 'width=device-width, initial-scale=1' },␊
+          { hid: 'description', name: 'description', content: '' }␊
+        ],␊
+        link: [␊
+          { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }␊
+        ]␊
+      },␊
+    ␊
+      // Global CSS (https://go.nuxtjs.dev/config-css)␊
+      css: [␊
+      ],␊
+    ␊
+      // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)␊
+      plugins: [␊
+      ],␊
+    ␊
+      // Auto import components (https://go.nuxtjs.dev/config-components)␊
+      components: true,␊
+    ␊
+      // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)␊
+      buildModules: [␊
+      ],␊
+    ␊
+      // Modules (https://go.nuxtjs.dev/config-modules)␊
+      modules: [␊
+      ],␊
+    ␊
+      // Build Configuration (https://go.nuxtjs.dev/config-build)␊
+      build: {␊
+      }␊
+    }␊
+    `
+
+## verify ci: None
+
+> Generated files
+
+    [
+      '.editorconfig',
+      '.gitignore',
+      'README.md',
+      'assets/README.md',
+      'components/Logo.vue',
+      'components/README.md',
+      'layouts/README.md',
+      'layouts/default.vue',
+      'middleware/README.md',
+      'nuxt.config.js',
+      'package.json',
+      'pages/README.md',
+      'pages/index.vue',
+      'plugins/README.md',
+      'static/README.md',
+      'static/favicon.ico',
+      'store/README.md',
+    ]
+
+> package.json
+
+    {
+      dependencies: {
+        'core-js': '^3.6.5',
+        nuxt: '^2.14.6',
+      },
+      devDependencies: {},
+      private: true,
+      scripts: {
+        build: 'nuxt build',
+        dev: 'nuxt',
+        generate: 'nuxt generate',
+        start: 'nuxt start',
+      },
+    }
+
+> Generated nuxt.config.js
+
+    `export default {␊
+      // Global page headers (https://go.nuxtjs.dev/config-head)␊
+      head: {␊
+        title: 'output',␊
+        meta: [␊
+          { charset: 'utf-8' },␊
+          { name: 'viewport', content: 'width=device-width, initial-scale=1' },␊
+          { hid: 'description', name: 'description', content: '' }␊
+        ],␊
+        link: [␊
+          { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }␊
+        ]␊
+      },␊
+    ␊
+      // Global CSS (https://go.nuxtjs.dev/config-css)␊
+      css: [␊
+      ],␊
+    ␊
+      // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)␊
+      plugins: [␊
+      ],␊
+    ␊
+      // Auto import components (https://go.nuxtjs.dev/config-components)␊
+      components: true,␊
+    ␊
+      // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)␊
+      buildModules: [␊
+      ],␊
+    ␊
+      // Modules (https://go.nuxtjs.dev/config-modules)␊
+      modules: [␊
+      ],␊
+    ␊
+      // Build Configuration (https://go.nuxtjs.dev/config-build)␊
+      build: {␊
+      }␊
+    }␊
+    `
+
 ## verify default answers
 
 > Generated files