9

有关的

我能够使用grunt-ssh将 Grunt 任务设置为 SFTP 文件到我的开发服务器:

sftp: {
    dev: {
        files: {
            './': ['**','!{node_modules,artifacts,sql,logs}/**'],
        },
        options: {
            path: '/path/to/project',
            privateKey: grunt.file.read(process.env.HOME+'/.ssh/id_rsa'),
            host: '111.111.111.111',
            port: 22,
            username: 'marksthebest',
        }
    }
},

但是,当我运行它时,它会上传所有内容。有数千个文件。每次修改文件都没有时间等他们一一上传。

我如何设置手表只上传我更改的文件,一旦我更改了它们?

(出于好奇,服务器是本地网络上的虚拟机。它在不同的操作系统上运行,并且设置比我的本地机器更类似于生产。如果我能正常工作,上传应该很快)

4

5 回答 5

7

您需要的是grunt-newer,该任务专门设计用于根据刚刚更改的文件更新任何任务的配置,然后运行它。示例配置可能如下所示:

watch: {
  all: {
    files: ['**','!{node_modules,artifacts,sql,logs}/**'],
    tasks: ['newer:sftp:dev']
  }
}
于 2013-12-05T20:40:50.007 回答
5

您可以使用 的 watch 事件来做到这一点grunt-contrib-watch。您基本上需要处理监视事件,修改 sftp 文件配置以仅包含更改的文件,然后让 grunt 运行 sftp 任务。

像这样的东西:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        secret: grunt.file.readJSON('secret.json'),
        watch: {
            test: {
                files: 'files/**/*',
                tasks: 'sftp',
                options: {
                    spawn: false
                }
            }
        },
        sftp: {
          test: {
            files: {
              "./": "files/**/*"
            },
            options: {
              path: '/path/on/the/server/',
              srcBasePath: 'files/',
              host: 'hostname.com',
              username: '<%= secret.username %>',
              password: '<%= secret.password %>',
              showProgress: true
            }
          }
        }
    }); // end grunt.initConfig

    // on watch events configure sftp.test.files to only run on changed file
    grunt.event.on('watch', function(action, filepath) {
        grunt.config('sftp.test.files', {"./": filepath});
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-ssh');
};

请注意“spawn: false”选项,以及您需要在事件处理程序中设置配置的方式。

注意2:此代码将一次上传一个文件,同一链接中有更强大的方法。

于 2014-05-15T21:15:06.690 回答
3

您可以使用 Grunt 来实现:

  • grunt-contrib-watch

  • grunt-rsync

首先要做的事情:我使用的是 Docker 容器。我还在我的 Docker 容器中添加了一个公共 SSH 密钥。因此,我仅将使用此 Grunt 任务在本地环境中更改的文件上传到我的“远程”容器中:

'use strict';

module.exports = function(grunt) {

    grunt.initConfig({

        rsync: {
            options: {
                args: ['-avz', '--verbose', '--delete'],
                exclude: ['.git*', 'cache', 'log'],
                recursive: true
            },
            development: {
                options: {
                    src: './',
                    dest: '/var/www/development',
                    host: 'root@www.localhost.com',
                    port: 2222
                }
            }
        },

        sshexec: {
            development: {
                command: 'chown -R www-data:www-data /var/www/development',
                options: {
                    host: 'www.localhost.com',
                    username: 'root',
                    port: 2222,
                    privateKey: grunt.file.read("/Users/YOUR_USER/.ssh/id_containers_rsa")
                }
            }
        },

        watch: {
            development: {
                files: [
                'node_modules',
                'package.json',
                'Gruntfile.js',
                '.gitignore',
                '.htaccess',
                'README.md',
                'config/*',
                'modules/*',
                'themes/*',
                '!cache/*',
                '!log/*'
                ],
                tasks: ['rsync:development', 'sshexec:development']
            }
        },

    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-rsync');
    grunt.loadNpmTasks('grunt-ssh');

    grunt.registerTask('default', ['watch:development']);
};

祝你好运,黑客快乐!

于 2014-12-30T16:22:20.773 回答
2

我最近遇到了一个类似的问题,我只想上传已更改的文件。我只使用grunt-exec. 如果您可以ssh访问您的服务器,您可以更高效地完成此任务。我还创建了一个rsync.json被 忽略的git,因此协作者可以拥有自己的 rsync 数据。

好处是,如果有人进行更改,它会自动上传到他们的舞台。

    // Watch - runs tasks when any changes are detected.
    watch: {
        scripts: {
            files: '**/*',
            tasks: ['deploy'],
            options: {
                spawn: false
            }
        }
    }

我的部署任务是一个注册任务,它编译脚本然后运行exec:deploy

   // Showing exec:deploy task 
   // Using rsync with ssh keys instead of login/pass
    exec: {
        deploy: {
            cmd: 'rsync public_html/* <%= rsync.options %> <%= rsync.user %>@<%= rsync.host %>:<%=rsync.path %>'
    }

你看到很多<%= rsync %>东西?我用它来获取rysnc.jsongit 获取的信息。我只有这个,因为这是一个团队工作流程。

// rsync.json
{
  "options": "-rvp --progress -a --delete -e 'ssh -q'",
  "user": "mmcfarland",
  "host": "example.com",
  "path": "~/stage/public_html"
}

确保您rsync.json在 grunt 中定义:

module.exports = function(grunt) {

  var rsync = grunt.file.readJSON('path/to/rsync.json');
  var pkg = grunt.file.readJSON('path/to/package.json');

  grunt.initConfig({
    pkg: pkg,
    rsync: rsync,
于 2014-06-16T16:00:44.623 回答
0

我认为将所有更改的内容一次上传到登台服务器并不是一个好主意。在登台服务器上工作也不是一个好主意。您必须配置本地机器服务器,与登台/生产相同

最好在进行部署时上传 1 次。

您可以使用 grunt-contrib-compress 归档所有文件。并使用 grunt-ssh 将它们作为 1 个文件推送,然后将其提取到服务器上,这样会快得多。

这是压缩任务的示例:

compress: {
            main: {
                options:{
                    archive:'build/build.tar.gz',
                    mode: 'tgz'
                },
                files: [
                    {cwd: 'build/', src: ['sites/all/modules/**'], dest:'./'},
                    {cwd: 'build/', src: ['sites/all/themes/**'], dest:'./'},
                    {cwd: 'build/', src: ['sites/default/files/**'], dest:'./'}
                ]
            }
        }

PS:从来没有考虑过 rsync grunt 模块。我知道这可能不是您想要的。但我决定将我的答案创建为独立答案。

于 2014-02-25T10:22:38.153 回答