diff --git a/lib/workers/branch/lock-files.js b/lib/workers/branch/lock-files.js
index 28829ee73990810d3b6ce6e101e49f7dffaa0152..bef878c5f2f6ccb859512331d779a3a35ba44ee4 100644
--- a/lib/workers/branch/lock-files.js
+++ b/lib/workers/branch/lock-files.js
@@ -67,6 +67,11 @@ function determineLockFileDirs(config) {
     }
   }
 
+  // If yarn workspaces are in use, then we need to generate yarn.lock from root dir
+  if (config.updatedPackageFiles.length && config.hasYarnWorkspaces) {
+    yarnLockFileDirs.push(path.dirname('package.json'));
+  }
+
   return { yarnLockFileDirs, packageLockFileDirs };
 }
 
diff --git a/lib/workers/package-file/index.js b/lib/workers/package-file/index.js
index 46916f359dec71776d3e02d5a510528f3deaa492..b570401bdb799a10f8df370035408b77a6e22e67 100644
--- a/lib/workers/package-file/index.js
+++ b/lib/workers/package-file/index.js
@@ -23,17 +23,6 @@ async function renovatePackageFile(packageFileConfig) {
     return upgrades;
   }
 
-  // Warn if workspaces found
-  if (config.content.workspaces) {
-    logger.warn('Found workspaces');
-    const warn = { ...config };
-    warn.depName = 'workspaces';
-    warn.type = 'warning';
-    warn.message =
-      'workspaces configuration detected in `package.json` but this is currently unsupported. Please see https://github.com/singapore/renovate/issues/473 for details.';
-    upgrades.push(warn);
-  }
-
   const depTypes = [
     'dependencies',
     'devDependencies',
diff --git a/lib/workers/repository/apis.js b/lib/workers/repository/apis.js
index a8458b3e18974f667acf46f2bd0d13efbff244b3..55bfb0916885bc9d727a034dd7c11a59cd87103a 100644
--- a/lib/workers/repository/apis.js
+++ b/lib/workers/repository/apis.js
@@ -206,30 +206,42 @@ async function mergeRenovateJson(config, branchName) {
 
 async function detectPackageFiles(input) {
   const config = { ...input };
-  config.logger.trace({ config }, 'detectPackageFiles');
+  const { logger } = config;
+  logger.trace({ config }, 'detectPackageFiles');
   config.packageFiles = await config.api.findFilePaths('package.json');
-  config.logger.debug(
+  logger.debug(
     { packageFiles: config.packageFiles },
     `Found ${config.packageFiles.length} package file(s)`
   );
   if (Array.isArray(config.ignorePaths)) {
+    logger.debug('Checking ignorePaths');
     const skippedPackageFiles = [];
     config.packageFiles = config.packageFiles.filter(packageFile => {
+      logger.trace(`Checking ${packageFile}`);
       if (
-        config.ignorePaths.some(ignorePath => packageFile.includes(ignorePath))
+        config.ignorePaths.some(ignorePath => {
+          logger.trace(` ..against ${ignorePath}`);
+          return packageFile.includes(ignorePath);
+        })
       ) {
+        logger.trace('Filtered out');
         skippedPackageFiles.push(packageFile);
         return false;
       }
+      logger.trace('Included');
       return true;
     });
     if (skippedPackageFiles.length) {
+      logger.debug(
+        { skippedPackageFiles },
+        `Skipped ${skippedPackageFiles.length} file(s)`
+      );
       config.foundIgnoredPaths = true;
       config.warnings.push({
         depName: 'packageFiles',
         message: `Skipped package.json files found within ignored paths: \`${skippedPackageFiles}\``,
       });
-      config.logger.debug(
+      logger.debug(
         `Now have ${config.packageFiles.length} package file(s) after filtering`
       );
     }
@@ -264,6 +276,14 @@ async function resolvePackageFiles(inputConfig) {
       config.baseBranch
     );
     if (packageFile.content) {
+      // check for workspaces
+      if (
+        packageFile.packageFile === 'package.json' &&
+        packageFile.content.workspaces
+      ) {
+        config.logger.info('Found yarn workspaces configuration');
+        config.hasYarnWorkspaces = true;
+      }
       // hoist renovate config if exists
       if (packageFile.content.renovate) {
         config.hasPackageJsonRenovateConfig = true;
diff --git a/test/workers/branch/__snapshots__/lock-files.spec.js.snap b/test/workers/branch/__snapshots__/lock-files.spec.js.snap
index 5e234a665e565d92fb9fbfd70788a961aa83a60e..dc3f6ab903bcef49386175b13446a55b29a447e5 100644
--- a/test/workers/branch/__snapshots__/lock-files.spec.js.snap
+++ b/test/workers/branch/__snapshots__/lock-files.spec.js.snap
@@ -22,6 +22,15 @@ Object {
 }
 `;
 
+exports[`workers/branch/lock-files determineLockFileDirs returns root directory if using yarn workspaces 1`] = `
+Object {
+  "packageLockFileDirs": Array [],
+  "yarnLockFileDirs": Array [
+    ".",
+  ],
+}
+`;
+
 exports[`workers/branch/lock-files getUpdatedLockFiles adds multiple lock files 1`] = `
 Object {
   "lockFileError": false,
diff --git a/test/workers/branch/lock-files.spec.js b/test/workers/branch/lock-files.spec.js
index d4231e658fc3cc14f0a61ec95cb89d2d0274cd2f..05cdbd3bf5b239d95d67097955523ad98062e356 100644
--- a/test/workers/branch/lock-files.spec.js
+++ b/test/workers/branch/lock-files.spec.js
@@ -149,6 +149,30 @@ describe('workers/branch/lock-files', () => {
       const res = determineLockFileDirs(config);
       expect(res).toMatchSnapshot();
     });
+    it('returns root directory if using yarn workspaces', () => {
+      config.hasYarnWorkspaces = true;
+      config.upgrades = [{}];
+      config.packageFiles = [
+        {
+          packageFile: 'package.json',
+          hasYarnLock: true,
+        },
+        {
+          packageFile: 'backend/package.json',
+        },
+      ];
+      config.updatedPackageFiles = [
+        {
+          name: 'backend/package.json',
+          contents: 'some contents',
+        },
+      ];
+      const res = determineLockFileDirs(config);
+      expect(res).toMatchSnapshot();
+      expect(res.packageLockFileDirs).toHaveLength(0);
+      expect(res.yarnLockFileDirs).toHaveLength(1);
+      expect(res.yarnLockFileDirs[0]).toEqual('.');
+    });
   });
   describe('writeExistingFiles', () => {
     let config;
diff --git a/test/workers/package-file/index.spec.js b/test/workers/package-file/index.spec.js
index 826d8f16eaf059251e61acd40495d335ac5936bf..453f1cd484696b01217622b8ca62beedd5191e8e 100644
--- a/test/workers/package-file/index.spec.js
+++ b/test/workers/package-file/index.spec.js
@@ -26,12 +26,6 @@ describe('packageFileWorker', () => {
       const res = await packageFileWorker.renovatePackageFile(config);
       expect(res).toEqual([]);
     });
-    it('warns if using workspaces', async () => {
-      config.content.workspaces = {};
-      const res = await packageFileWorker.renovatePackageFile(config);
-      expect(res).toHaveLength(1);
-      expect(res[0].type).toEqual('warning');
-    });
     it('returns upgrades', async () => {
       depTypeWorker.renovateDepType.mockReturnValueOnce([{}]);
       depTypeWorker.renovateDepType.mockReturnValueOnce([{}, {}]);
diff --git a/test/workers/repository/__snapshots__/apis.spec.js.snap b/test/workers/repository/__snapshots__/apis.spec.js.snap
index d27792d0035d8ce7f29d66035eaf43d4823d0608..f3a1a1a96dee0893a5cfa920fecfb1d0aa4db146 100644
--- a/test/workers/repository/__snapshots__/apis.spec.js.snap
+++ b/test/workers/repository/__snapshots__/apis.spec.js.snap
@@ -93,7 +93,9 @@ exports[`workers/repository/apis mergeRenovateJson(config) returns warning + err
 exports[`workers/repository/apis resolvePackageFiles includes files with content 1`] = `
 Array [
   Object {
-    "content": Object {},
+    "content": Object {
+      "workspaces": Array [],
+    },
     "errors": Array [],
     "hasPackageLock": true,
     "hasYarnLock": true,
diff --git a/test/workers/repository/apis.spec.js b/test/workers/repository/apis.spec.js
index 872bc8ab7c10b341730ef02b6183d54aa6c9cf65..346eee59e40520ac2354986bdb91f850219f2558 100644
--- a/test/workers/repository/apis.spec.js
+++ b/test/workers/repository/apis.spec.js
@@ -285,7 +285,10 @@ describe('workers/repository/apis', () => {
       expect(res.packageFiles).toEqual([]);
     });
     it('includes files with content', async () => {
-      config.api.getFileJson.mockReturnValueOnce({ renovate: {} });
+      config.api.getFileJson.mockReturnValueOnce({
+        renovate: {},
+        workspaces: [],
+      });
       config.api.getFileJson.mockReturnValueOnce({});
       config.api.getFileContent.mockReturnValueOnce(null);
       config.api.getFileContent.mockReturnValueOnce(null);