Compare commits
80 commits
Author | SHA1 | Date | |
---|---|---|---|
|
243ab38b08 | ||
|
32d7897b66 | ||
|
9cd8988a66 | ||
|
86f76b2a53 | ||
|
751c11f6eb | ||
|
c590d005cf | ||
|
1806c9263b | ||
|
a8c6fdafef | ||
|
9eece01aef | ||
|
000cabda96 | ||
|
4b79845d53 | ||
|
21d04f253a | ||
|
7360fcadc4 | ||
|
bd5e214614 | ||
|
217af0d33c | ||
|
8a0bfaec2b | ||
|
79d86af7be | ||
|
b84f69f54a | ||
|
c466746266 | ||
|
546542032f | ||
|
5486033a11 | ||
|
70863dc312 | ||
|
6e7ce4d72d | ||
|
e14f90fe1d | ||
|
359f7d7431 | ||
|
2aba441a30 | ||
|
bfe6473000 | ||
|
4f9d4879d7 | ||
|
84b3cb0121 | ||
|
71c4e6339b | ||
|
b8069d3144 | ||
|
fa339eba4f | ||
|
84e86e2530 | ||
|
efd66e7fca | ||
|
08e392fc6b | ||
|
4fe4526807 | ||
|
6c426c0ef3 | ||
|
c381b6448f | ||
|
da58498102 | ||
|
d494a4faf7 | ||
|
dca25529a3 | ||
|
774e656cfa | ||
|
8226bba8b3 | ||
|
e729af6b02 | ||
|
0bd94419ea | ||
|
e89b403ad8 | ||
|
865b98f1c0 | ||
|
c22ff4bc15 | ||
|
1d120c0112 | ||
|
ae68d40616 | ||
|
dbaef1ead7 | ||
|
669763b878 | ||
|
4e46a4e3e7 | ||
|
a7e90214f2 | ||
|
260665eef9 | ||
|
08875eebec | ||
|
83c24d7443 | ||
|
11860dd930 | ||
|
064b17add2 | ||
|
23c6b8c1f6 | ||
|
b0f7cde56a | ||
|
26f2e43a52 | ||
|
64ffb98d14 | ||
|
eaedc962b8 | ||
|
5b1723ab34 | ||
|
63a9e82bd2 | ||
|
23cace3319 | ||
|
36785eb98f | ||
|
273174f427 | ||
|
0b0f447117 | ||
|
4f03a0eaa1 | ||
|
0f1a55a82b | ||
|
d845e9f42d | ||
|
c981ca3aa0 | ||
|
fd5fa8c04d | ||
|
268ddb1a14 | ||
|
2f8d236ee4 | ||
|
cbead1ee4b | ||
|
6eed387731 | ||
|
336fcd3c0e |
16
.gitignore
vendored
16
.gitignore
vendored
|
@ -1,2 +1,18 @@
|
||||||
|
*.gem
|
||||||
|
*.rbc
|
||||||
|
.bundle
|
||||||
|
.config
|
||||||
|
.yardoc
|
||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
|
InstalledFiles
|
||||||
|
_yardoc
|
||||||
coverage
|
coverage
|
||||||
|
doc/
|
||||||
|
lib/bundler/man
|
||||||
|
pkg
|
||||||
|
rdoc
|
||||||
|
spec/reports
|
||||||
|
test/tmp
|
||||||
|
test/version_tmp
|
||||||
|
tmp
|
||||||
|
bin
|
11
.rubocop.yml
Normal file
11
.rubocop.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
AllCops:
|
||||||
|
Include:
|
||||||
|
- 'Gemfile'
|
||||||
|
Exclude:
|
||||||
|
- 'script/**/*'
|
||||||
|
- 'vendor/**/*'
|
||||||
|
- 'bin/**/*'
|
||||||
|
Documentation:
|
||||||
|
Enabled: false
|
||||||
|
ClassAndModuleChildren:
|
||||||
|
Enabled: false
|
26
.travis.yml
Normal file
26
.travis.yml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
language: ruby
|
||||||
|
sudo: false
|
||||||
|
cache: bundler
|
||||||
|
bundler_args: --without development
|
||||||
|
rvm:
|
||||||
|
- ruby-head
|
||||||
|
- ruby
|
||||||
|
- jruby-head
|
||||||
|
- jruby
|
||||||
|
- 2.1.0
|
||||||
|
- 2.0.0
|
||||||
|
- 1.9.3
|
||||||
|
- rbx-2
|
||||||
|
before_script: bundle update
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
allow_failures:
|
||||||
|
- rvm: ruby-head
|
||||||
|
- rvm: ruby
|
||||||
|
- rvm: jruby-head
|
||||||
|
- rvm: jruby
|
||||||
|
- rvm: rbx-2
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
|
env:
|
||||||
|
- CODECLIMATE_REPO_TOKEN=5eee8e8624962f963a52a1d2313dc7407e3b8006291e3704346c786642cc073b
|
6
.yardopts
Normal file
6
.yardopts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
--markup markdown
|
||||||
|
-
|
||||||
|
CHANGELOG.md
|
||||||
|
CONTRIBUTING.md
|
||||||
|
LICENSE.md
|
||||||
|
README.md
|
12
CHANGELOG.md
Normal file
12
CHANGELOG.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Next Release
|
||||||
|
============
|
||||||
|
* Your contribution here.
|
||||||
|
|
||||||
|
2.0.0-alpha (02/08/2015)
|
||||||
|
==================
|
||||||
|
* [Fixing compatibility issues with middleman v4.0.0.beta.1](https://github.com/middleman-contrib/middleman-deploy/pull/87) - [@emilioforrer](https://github.com/emilioforrer).
|
||||||
|
|
||||||
|
1.0.0 (16/07/2014)
|
||||||
|
==================
|
||||||
|
* [Respect user details of git repo](https://github.com/middleman-contrib/middleman-deploy/pull/70) - [@Gee-Bee](https://github.com/gee-bee).
|
||||||
|
* [Prevent bad commits deploying](https://github.com/middleman-contrib/middleman-deploy/pull/77) - [@karlfreeman](https://github.com/mconnell).
|
44
CONTRIBUTING.md
Normal file
44
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
## Contributing
|
||||||
|
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
||||||
|
improve this project.
|
||||||
|
|
||||||
|
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
||||||
|
|
||||||
|
Here are some ways *you* can contribute:
|
||||||
|
|
||||||
|
* by using alpha, beta, and prerelease versions
|
||||||
|
* by reporting bugs
|
||||||
|
* by suggesting new features
|
||||||
|
* by writing or editing documentation
|
||||||
|
* by writing specifications
|
||||||
|
* by writing code (**no patch is too small**: fix typos, add comments, clean up
|
||||||
|
inconsistent whitespace)
|
||||||
|
* by refactoring code
|
||||||
|
* by closing [issues][]
|
||||||
|
* by reviewing patches
|
||||||
|
|
||||||
|
[issues]: https://github.com/karlfreeman/middleman-deploy/issues
|
||||||
|
|
||||||
|
## Submitting an Issue
|
||||||
|
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
||||||
|
submitting a bug report or feature request, check to make sure it hasn't
|
||||||
|
already been submitted. When submitting a bug report, please include a [Gist][]
|
||||||
|
that includes a stack trace and any details that may be necessary to reproduce
|
||||||
|
the bug, including your gem version, Ruby version, and operating system.
|
||||||
|
Ideally, a bug report should include a pull request with failing specs.
|
||||||
|
|
||||||
|
[gist]: https://gist.github.com/
|
||||||
|
|
||||||
|
## Submitting a Pull Request
|
||||||
|
1. [Fork the repository.][fork]
|
||||||
|
2. [Create a topic branch.][branch]
|
||||||
|
3. Add specs for your unimplemented feature or bug fix.
|
||||||
|
4. Run `bundle exec rake cucumber`. If your specs pass, return to step 3.
|
||||||
|
5. Implement your feature or bug fix.
|
||||||
|
6. Run `bundle exec rake cucumber`. If your specs fail, return to step 5.
|
||||||
|
7. Add, commit, and push your changes.
|
||||||
|
9. [Submit a pull request.][pr]
|
||||||
|
|
||||||
|
[fork]: http://help.github.com/fork-a-repo/
|
||||||
|
[branch]: http://learn.github.com/p/branching.html
|
||||||
|
[pr]: http://help.github.com/send-pull-requests/
|
18
Gemfile
18
Gemfile
|
@ -1,19 +1,11 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
# Specify your gem's dependencies in middleman-deploy.gemspec
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
group :development do
|
|
||||||
gem "rake"
|
|
||||||
gem "rdoc"
|
|
||||||
gem "yard"
|
|
||||||
end
|
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem "compass"
|
gem 'rake', '~> 10.0'
|
||||||
gem "cucumber"
|
gem 'cucumber', '~> 1.3'
|
||||||
gem "fivemat"
|
gem 'aruba', '~> 0.5'
|
||||||
gem "aruba"
|
gem 'fivemat'
|
||||||
gem "rspec"
|
gem 'codeclimate-test-reporter'
|
||||||
gem "simplecov"
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
Copyright (c) 2012 Tom Vaughan <thomas.david.vaughan@gmail.com>
|
Copyright (c) 2012-2014 Tom Vaughan, Karl Freeman
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
@ -8,13 +10,13 @@ distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
the following conditions:
|
the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
The above copyright notice and this permission notice shall be
|
||||||
in all copies or substantial portions of the Software.
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
222
README.md
222
README.md
|
@ -1,18 +1,13 @@
|
||||||
# middleman-deploy [![Build Status](https://travis-ci.org/tvaughan/middleman-deploy.png?branch=master)](https://travis-ci.org/tvaughan/middleman-deploy)
|
# Middleman Deploy
|
||||||
|
|
||||||
Deploys a [middleman](http://middlemanapp.com/) built site via **rsync**,
|
Deploy your [Middleman](http://middlemanapp.com/) build via **rsync**, **ftp**, **sftp**, or **git** (e.g. [gh-pages on github](https://help.github.com/articles/creating-project-pages-manually)).
|
||||||
**ftp**, **sftp**, or **git** (e.g. gh-pages on github).
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add this to the Gemfile of the repository of your middleman site:
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
gem "middleman-deploy"
|
gem 'middleman-deploy', '~> 1.0'
|
||||||
```
|
```
|
||||||
|
|
||||||
and run `bundle install`.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -20,6 +15,87 @@ $ middleman build [--clean]
|
||||||
$ middleman deploy [--build-before]
|
$ middleman deploy [--build-before]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Possible Configurations
|
||||||
|
|
||||||
|
Middleman-deploy can deploy a site via rsync, ftp, sftp, or git. Checkout [the wiki](https://github.com/tvaughan/middleman-deploy/wiki/_pages) for advanced set-up options.
|
||||||
|
|
||||||
|
### Rsync
|
||||||
|
|
||||||
|
Make sure that `rsync` is installed, and activate the extension by adding the
|
||||||
|
following to `config.rb`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.deploy_method = :rsync
|
||||||
|
deploy.host = 'www.example.com'
|
||||||
|
deploy.path = '/srv/www/site'
|
||||||
|
# Optional Settings
|
||||||
|
# deploy.user = 'tvaughan' # no default
|
||||||
|
# deploy.port = 5309 # ssh port, default: 22
|
||||||
|
# deploy.clean = true # remove orphaned files on remote host, default: false
|
||||||
|
# deploy.flags = '-rltgoDvzO --no-p --del' # add custom flags, default: -avz
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Git (e.g. GitHub Pages)
|
||||||
|
|
||||||
|
Make sure that `git` is installed, and activate the extension by adding the
|
||||||
|
following to `config.rb`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.deploy_method = :git
|
||||||
|
# Optional Settings
|
||||||
|
# deploy.remote = 'custom-remote' # remote name or git url, default: origin
|
||||||
|
# deploy.branch = 'custom-branch' # default: gh-pages
|
||||||
|
# deploy.strategy = :submodule # commit strategy: can be :force_push or :submodule, default: :force_push
|
||||||
|
# deploy.commit_message = 'custom-message' # commit message (can be empty), default: Automated commit at `timestamp` by middleman-deploy `version`
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
If you use a remote name, you must first add it using `git remote add`. Run
|
||||||
|
`git remote -v` to see a list of possible remote names. If you use a git url,
|
||||||
|
it must end with '.git'.
|
||||||
|
|
||||||
|
Afterwards, the `build` directory will become a git repo.
|
||||||
|
|
||||||
|
If you use the force push strategy, this branch will be created on the remote if
|
||||||
|
it doesn't already exist.
|
||||||
|
But if you use the submodule strategy, you must first initialize build folder as
|
||||||
|
a submodule. See `git submodule add` documentation.
|
||||||
|
|
||||||
|
### FTP
|
||||||
|
|
||||||
|
Activate the extension by adding the following to `config.rb`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.deploy_method = :ftp
|
||||||
|
deploy.host = 'ftp.example.com'
|
||||||
|
deploy.path = '/srv/www/site'
|
||||||
|
deploy.user = 'tvaughan'
|
||||||
|
deploy.password = 'secret'
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### SFTP
|
||||||
|
|
||||||
|
Activate the extension by adding the following to `config.rb`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.deploy_method = :sftp
|
||||||
|
deploy.host = 'sftp.example.com'
|
||||||
|
deploy.port = 22
|
||||||
|
deploy.path = '/srv/www/site'
|
||||||
|
# Optional Settings
|
||||||
|
# deploy.user = 'tvaughan' # no default
|
||||||
|
# deploy.password = 'secret' # no default
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Automatically
|
||||||
|
|
||||||
To automatically run `middleman build` during `middleman deploy`, turn on the
|
To automatically run `middleman build` during `middleman deploy`, turn on the
|
||||||
`build_before` option while activating the deploy extension:
|
`build_before` option while activating the deploy extension:
|
||||||
|
|
||||||
|
@ -30,95 +106,81 @@ activate :deploy do |deploy|
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
## Possible Configurations
|
### Multiple Environments
|
||||||
|
|
||||||
Middleman-deploy can deploy a site via rsync, ftp, sftp, or git.
|
Deploy your site to more than one configuration using environment variables.
|
||||||
|
|
||||||
### rsync
|
|
||||||
|
|
||||||
Make sure that `rsync` is installed, and activate the extension by adding the
|
|
||||||
following to `config.rb`:
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
activate :deploy do |deploy|
|
# config.rb
|
||||||
deploy.method = :rsync
|
case ENV['TARGET'].to_s.downcase
|
||||||
deploy.host = "www.example.com"
|
when 'production'
|
||||||
deploy.path = "/srv/www/site"
|
activate :deploy do |deploy|
|
||||||
# Optional Settings
|
deploy.deploy_method = :rsync
|
||||||
# deploy.user = "tvaughan" # no default
|
deploy.host = 'www.example.com'
|
||||||
# deploy.port = 5309 # ssh port, default: 22
|
deploy.path = '/srv/www/production-site'
|
||||||
# deploy.clean = true # remove orphaned files on remote host, default: false
|
end
|
||||||
|
else
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.deploy_method = :rsync
|
||||||
|
deploy.host = 'staging.example.com'
|
||||||
|
deploy.path = '/srv/www/staging-site'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
### Git (e.g. GitHub Pages)
|
|
||||||
|
|
||||||
Make sure that `git` is installed, and activate the extension by adding the
|
|
||||||
following to `config.rb`:
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
activate :deploy do |deploy|
|
# Rakefile
|
||||||
deploy.method = :git
|
namespace :deploy do
|
||||||
# Optional Settings
|
def deploy(env)
|
||||||
# deploy.remote = "custom-remote" # remote name or git url, default: origin
|
puts "Deploying to #{env}"
|
||||||
# deploy.branch = "custom-branch" # default: gh-pages
|
system "TARGET=#{env} bundle exec middleman deploy"
|
||||||
|
end
|
||||||
|
|
||||||
|
task :staging do
|
||||||
|
deploy :staging
|
||||||
|
end
|
||||||
|
|
||||||
|
task :production do
|
||||||
|
deploy :production
|
||||||
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use a remote name, you must first add it using `git remote add`. Run
|
```
|
||||||
`git remote -v` to see a list of possible remote names. If you use a git url,
|
$ rake deploy:staging
|
||||||
it must end with '.git'.
|
$ rake deploy:production
|
||||||
|
|
||||||
Afterwards, the `build` directory will become a git repo. This branch will be
|
|
||||||
created on the remote if it doesn't already exist.
|
|
||||||
|
|
||||||
### FTP
|
|
||||||
|
|
||||||
Activate the extension by adding the following to `config.rb`:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
activate :deploy do |deploy|
|
|
||||||
deploy.method = :ftp
|
|
||||||
deploy.host = "ftp.example.com"
|
|
||||||
deploy.user = "tvaughan"
|
|
||||||
deploy.password = "secret"
|
|
||||||
deploy.path = "/srv/www/site"
|
|
||||||
end
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### SFTP
|
## Badges
|
||||||
|
|
||||||
Activate the extension by adding the following to `config.rb`:
|
[![Gem Version](http://img.shields.io/gem/v/middleman-deploy.svg)][gem]
|
||||||
|
[![Build Status](http://img.shields.io/travis/karlfreeman/middleman-deploy.svg)][travis]
|
||||||
|
[![Code Quality](http://img.shields.io/codeclimate/github/karlfreeman/middleman-deploy.svg)][codeclimate]
|
||||||
|
[![Code Coverage](http://img.shields.io/codeclimate/coverage/github/karlfreeman/middleman-deploy.svg)][codeclimate]
|
||||||
|
[![Gittip](http://img.shields.io/gittip/karlfreeman.svg)][gittip]
|
||||||
|
|
||||||
```ruby
|
## Supported Ruby Versions
|
||||||
activate :deploy do |deploy|
|
|
||||||
deploy.method = :sftp
|
|
||||||
deploy.host = "sftp.example.com"
|
|
||||||
deploy.user = "tvaughan"
|
|
||||||
deploy.password = "secret"
|
|
||||||
deploy.path = "/srv/www/site"
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
## Breaking Changes
|
This library aims to support and is [tested against][travis] the following Ruby
|
||||||
|
implementations:
|
||||||
|
|
||||||
* `v0.1.0`
|
- Ruby 2.1.0
|
||||||
- Removed the `--clean` command-line option. This option only applied to
|
- Ruby 2.0.0
|
||||||
the rsync deploy method. The idea going forward is that command-line
|
- Ruby 1.9.3
|
||||||
options must apply to all deploy methods. Options that are specific to a
|
- [JRuby][jruby]
|
||||||
deploy method will only be available in `config.rb`.
|
- [Rubinius][rubinius]
|
||||||
- Removed `deploy` from the `after_build` hook. This caused a `deploy` to
|
|
||||||
be run each time `build` was called. This workflow never made
|
|
||||||
sense. `deploy` was added to the `after_build` hook simply because it
|
|
||||||
was available.
|
|
||||||
|
|
||||||
## Thanks!
|
# Credits
|
||||||
|
|
||||||
A **BIG** thanks to
|
A **BIG** thanks to [everyone who has contributed](https://github.com/karlfreeman/middleman-deploy/graphs/contributors)! Almost all pull requests are accepted.
|
||||||
[everyone who has contributed](https://github.com/tvaughan/middleman-deploy/graphs/contributors)!
|
|
||||||
Almost all pull requests are accepted.
|
|
||||||
|
|
||||||
## Other
|
Inspiration:
|
||||||
|
|
||||||
Inspired by the rsync task in
|
- The rsync task in [Octopress](https://github.com/imathis/octopress)
|
||||||
[Octopress](https://github.com/imathis/octopress).
|
|
||||||
|
[gem]: https://rubygems.org/gems/middleman-deploy
|
||||||
|
[travis]: http://travis-ci.org/karlfreeman/middleman-deploy
|
||||||
|
[codeclimate]: https://codeclimate.com/github/karlfreeman/middleman-deploy
|
||||||
|
[gittip]: https://www.gittip.com/karlfreeman
|
||||||
|
[jruby]: http://www.jruby.org
|
||||||
|
[rubinius]: http://rubini.us
|
||||||
|
|
38
Rakefile
38
Rakefile
|
@ -1,35 +1,25 @@
|
||||||
require 'bundler'
|
require 'bundler'
|
||||||
|
Bundler.setup
|
||||||
Bundler::GemHelper.install_tasks
|
Bundler::GemHelper.install_tasks
|
||||||
|
|
||||||
require 'cucumber/rake/task'
|
require 'cucumber/rake/task'
|
||||||
|
|
||||||
Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t|
|
Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t|
|
||||||
t.cucumber_opts = "--color --tags ~@wip --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}"
|
exempt_tags = ['--tags ~@wip']
|
||||||
|
t.cucumber_opts = "--color #{exempt_tags.join(' ')} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}"
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'rake/clean'
|
begin
|
||||||
|
require 'yard'
|
||||||
task :test => ["cucumber"]
|
YARD::Rake::YardocTask.new
|
||||||
|
rescue LoadError
|
||||||
require "middleman-deploy/pkg-info"
|
|
||||||
|
|
||||||
PACKAGE = "#{Middleman::Deploy::PACKAGE}"
|
|
||||||
VERSION = "#{Middleman::Deploy::VERSION}"
|
|
||||||
|
|
||||||
task :package do
|
|
||||||
system "gem build #{PACKAGE}.gemspec"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
task :install => :package do
|
begin
|
||||||
Dir.chdir("pkg") do
|
require 'rubocop/rake_task'
|
||||||
system "gem install #{PACKAGE}-#{VERSION}"
|
desc 'Run rubocop'
|
||||||
end
|
RuboCop::RakeTask.new(:rubocop)
|
||||||
|
rescue LoadError
|
||||||
end
|
end
|
||||||
|
|
||||||
task :release => :package do
|
task default: :cucumber
|
||||||
Dir.chdir("pkg") do
|
task test: :cucumber
|
||||||
system "gem push #{PACKAGE}-#{VERSION}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
task :default => :test
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
require "simplecov"
|
|
||||||
SimpleCov.start
|
|
||||||
PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
|
PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
|
||||||
require "middleman-core"
|
require 'middleman-core'
|
||||||
require "middleman-core/step_definitions"
|
require 'middleman-core/step_definitions'
|
||||||
|
|
||||||
|
require 'codeclimate-test-reporter'
|
||||||
|
CodeClimate::TestReporter.start
|
||||||
|
|
||||||
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-deploy')
|
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-deploy')
|
||||||
|
|
6
features/test.feature
Normal file
6
features/test.feature
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Feature: test
|
||||||
|
|
||||||
|
Scenario: whilst testing
|
||||||
|
Given the Server is running at "test-app"
|
||||||
|
When I go to "/index.html"
|
||||||
|
Then I should see "<h1>Test</h1>"
|
0
fixtures/test-app/config.rb
Normal file
0
fixtures/test-app/config.rb
Normal file
1
fixtures/test-app/source/index.html.erb
Normal file
1
fixtures/test-app/source/index.html.erb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<h1>Test</h1>
|
|
@ -1,8 +1,8 @@
|
||||||
require "middleman-core"
|
require 'middleman-core'
|
||||||
|
|
||||||
require "middleman-deploy/commands"
|
require 'middleman-deploy/commands'
|
||||||
|
|
||||||
::Middleman::Extensions.register(:deploy) do
|
::Middleman::Extensions.register(:deploy) do
|
||||||
require "middleman-deploy/extension"
|
require 'middleman-deploy/extension'
|
||||||
::Middleman::Deploy
|
::Middleman::Deploy::Extension
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,286 +1,119 @@
|
||||||
require "middleman-core/cli"
|
require 'middleman-core/cli'
|
||||||
|
require 'middleman-core/rack' if Middleman::VERSION.to_i > 3
|
||||||
require "middleman-deploy/extension"
|
require 'middleman-deploy/pkg-info'
|
||||||
require "middleman-deploy/pkg-info"
|
require 'middleman-deploy/extension'
|
||||||
|
require 'middleman-deploy/methods'
|
||||||
|
require 'middleman-deploy/strategies'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
module Cli
|
module Cli
|
||||||
|
|
||||||
# This class provides a "deploy" command for the middleman CLI.
|
# This class provides a "deploy" command for the middleman CLI.
|
||||||
class Deploy < Thor
|
class Deploy < Thor::Group
|
||||||
include Thor::Actions
|
include Thor::Actions
|
||||||
|
|
||||||
check_unknown_options!
|
check_unknown_options!
|
||||||
|
|
||||||
namespace :deploy
|
namespace :deploy
|
||||||
|
|
||||||
|
class_option :environment,
|
||||||
|
aliases: '-e',
|
||||||
|
default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'production',
|
||||||
|
desc: 'The environment Middleman will run under'
|
||||||
|
|
||||||
|
class_option :verbose,
|
||||||
|
type: :boolean,
|
||||||
|
default: false,
|
||||||
|
desc: 'Print debug messages'
|
||||||
|
|
||||||
|
class_option :instrument,
|
||||||
|
type: :string,
|
||||||
|
default: false,
|
||||||
|
desc: 'Print instrument messages'
|
||||||
|
|
||||||
|
class_option :build_before,
|
||||||
|
type: :boolean,
|
||||||
|
aliases: '-b',
|
||||||
|
desc: 'Run `middleman build` before the deploy step'
|
||||||
|
|
||||||
|
def self.subcommand_help(_options)
|
||||||
|
# TODO
|
||||||
|
end
|
||||||
|
|
||||||
# Tell Thor to exit with a nonzero exit code on failure
|
# Tell Thor to exit with a nonzero exit code on failure
|
||||||
def self.exit_on_failure?
|
def self.exit_on_failure?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "deploy [options]", Middleman::Deploy::TAGLINE
|
|
||||||
method_option "build_before",
|
|
||||||
:type => :boolean,
|
|
||||||
:aliases => "-b",
|
|
||||||
:desc => "Run `middleman build` before the deploy step"
|
|
||||||
|
|
||||||
def deploy
|
def deploy
|
||||||
if options.has_key? "build_before"
|
env = options['environment'] ? :production : options['environment'].to_s.to_sym
|
||||||
build_before = options.build_before
|
verbose = options['verbose'] ? 0 : 1
|
||||||
else
|
instrument = options['instrument']
|
||||||
build_before = self.deploy_options.build_before
|
|
||||||
|
@app = ::Middleman::Application.new do
|
||||||
|
config[:mode] = :build
|
||||||
|
config[:environment] = env
|
||||||
|
::Middleman::Logger.singleton(verbose, instrument)
|
||||||
end
|
end
|
||||||
if build_before
|
build_before(options)
|
||||||
# http://forum.middlemanapp.com/t/problem-with-the-build-task-in-an-extension
|
process
|
||||||
run("middleman build") || exit(1)
|
|
||||||
end
|
|
||||||
send("deploy_#{self.deploy_options.method}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def print_usage_and_die(message)
|
def build_before(options = {})
|
||||||
raise Error, "ERROR: " + message + "\n" + <<EOF
|
build_enabled = options.fetch('build_before', deploy_options.build_before)
|
||||||
|
|
||||||
You should follow one of the four examples below to setup the deploy
|
if build_enabled
|
||||||
extension in config.rb.
|
# http://forum.middlemanapp.com/t/problem-with-the-build-task-in-an-extension
|
||||||
|
run("middleman build -e #{options['environment']}") || exit(1)
|
||||||
# To deploy the build directory to a remote host via rsync:
|
end
|
||||||
activate :deploy do |deploy|
|
|
||||||
deploy.method = :rsync
|
|
||||||
# host and path *must* be set
|
|
||||||
deploy.host = "www.example.com"
|
|
||||||
deploy.path = "/srv/www/site"
|
|
||||||
# user is optional (no default)
|
|
||||||
deploy.user = "tvaughan"
|
|
||||||
# port is optional (default is 22)
|
|
||||||
deploy.port = 5309
|
|
||||||
# clean is optional (default is false)
|
|
||||||
deploy.clean = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# To deploy to a remote branch via git (e.g. gh-pages on github):
|
|
||||||
activate :deploy do |deploy|
|
|
||||||
deploy.method = :git
|
|
||||||
# remote is optional (default is "origin")
|
|
||||||
# run `git remote -v` to see a list of possible remotes
|
|
||||||
deploy.remote = "some-other-remote-name"
|
|
||||||
# branch is optional (default is "gh-pages")
|
|
||||||
# run `git branch -a` to see a list of possible branches
|
|
||||||
deploy.branch = "some-other-branch-name"
|
|
||||||
end
|
|
||||||
|
|
||||||
# To deploy the build directory to a remote host via ftp:
|
|
||||||
activate :deploy do |deploy|
|
|
||||||
deploy.method = :ftp
|
|
||||||
# host, user, passwword and path *must* be set
|
|
||||||
deploy.host = "ftp.example.com"
|
|
||||||
deploy.user = "tvaughan"
|
|
||||||
deploy.password = "secret"
|
|
||||||
deploy.path = "/srv/www/site"
|
|
||||||
end
|
|
||||||
|
|
||||||
# To deploy the build directory to a remote host via sftp:
|
|
||||||
activate :deploy do |deploy|
|
|
||||||
deploy.method = :sftp
|
|
||||||
# host, user, passwword and path *must* be set
|
|
||||||
deploy.host = "sftp.example.com"
|
|
||||||
deploy.user = "tvaughan"
|
|
||||||
deploy.password = "secret"
|
|
||||||
deploy.path = "/srv/www/site"
|
|
||||||
end
|
|
||||||
EOF
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def inst
|
def print_usage_and_die(message)
|
||||||
::Middleman::Application.server.inst
|
fail StandardError, "ERROR: #{message}\n#{Middleman::Deploy::README}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
server_instance = @app
|
||||||
|
camelized_method = deploy_options.deploy_method.to_s.split('_').map(&:capitalize).join
|
||||||
|
method_class_name = "Middleman::Deploy::Methods::#{camelized_method}"
|
||||||
|
method_instance = method_class_name.constantize.new(server_instance, deploy_options)
|
||||||
|
|
||||||
|
method_instance.process
|
||||||
end
|
end
|
||||||
|
|
||||||
def deploy_options
|
def deploy_options
|
||||||
options = nil
|
options = nil
|
||||||
|
|
||||||
begin
|
begin
|
||||||
options = inst.options
|
options = ::Middleman::Deploy.options
|
||||||
rescue
|
rescue NoMethodError
|
||||||
print_usage_and_die "You need to activate the deploy extension in config.rb."
|
print_usage_and_die 'You need to activate the deploy extension in config.rb.'
|
||||||
end
|
end
|
||||||
|
|
||||||
if (!options.method)
|
unless options.deploy_method
|
||||||
print_usage_and_die "The deploy extension requires you to set a method."
|
print_usage_and_die 'The deploy extension requires you to set a method.'
|
||||||
end
|
end
|
||||||
|
|
||||||
case options.method
|
case options.deploy_method
|
||||||
when :rsync
|
when :rsync, :sftp
|
||||||
if (!options.host || !options.path)
|
unless options.host && options.path
|
||||||
print_usage_and_die "The rsync deploy method requires host and path to be set."
|
print_usage_and_die "The #{options.deploy_method} method requires host and path to be set."
|
||||||
end
|
end
|
||||||
when :ftp, :sftp
|
when :ftp
|
||||||
if (!options.host || !options.user || !options.password || !options.path)
|
unless options.host && options.user && options.password && options.path
|
||||||
print_usage_and_die "The #{options.method} method requires host, user, password, and path to be set."
|
print_usage_and_die 'The ftp deploy method requires host, path, user, and password to be set.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
def deploy_rsync
|
|
||||||
host = self.deploy_options.host
|
|
||||||
port = self.deploy_options.port
|
|
||||||
path = self.deploy_options.path
|
|
||||||
|
|
||||||
# Append "@" to user if provided.
|
|
||||||
user = self.deploy_options.user
|
|
||||||
user = "#{user}@" if user && !user.empty?
|
|
||||||
|
|
||||||
dest_url = "#{user}#{host}:#{path}"
|
|
||||||
|
|
||||||
puts "## Deploying via rsync to #{dest_url} port=#{port}"
|
|
||||||
|
|
||||||
command = "rsync -avze '" + "ssh -p #{port}" + "' #{self.inst.build_dir}/ #{dest_url}"
|
|
||||||
|
|
||||||
if self.deploy_options.clean
|
|
||||||
command += " --delete"
|
|
||||||
end
|
|
||||||
|
|
||||||
run command
|
|
||||||
end
|
|
||||||
|
|
||||||
def deploy_git
|
|
||||||
remote = self.deploy_options.remote
|
|
||||||
branch = self.deploy_options.branch
|
|
||||||
|
|
||||||
puts "## Deploying via git to remote=\"#{remote}\" and branch=\"#{branch}\""
|
|
||||||
|
|
||||||
#check if remote is not a git url
|
|
||||||
unless remote =~ /\.git$/
|
|
||||||
remote = `git config --get remote.#{remote}.url`.chop
|
|
||||||
end
|
|
||||||
|
|
||||||
#if the remote name doesn't exist in the main repo
|
|
||||||
if remote == ''
|
|
||||||
puts "Can't deploy! Please add a remote with the name '#{self.deploy_options.remote}' to your repo."
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
Dir.chdir(self.inst.build_dir) do
|
|
||||||
unless File.exists?('.git')
|
|
||||||
`git init`
|
|
||||||
`git remote add origin #{remote}`
|
|
||||||
else
|
|
||||||
#check if the remote repo has changed
|
|
||||||
unless remote == `git config --get remote.origin.url`.chop
|
|
||||||
`git remote rm origin`
|
|
||||||
`git remote add origin #{remote}`
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#if there is a branch with that name, switch to it, otherwise create a new one and switch to it
|
|
||||||
if `git branch`.split("\n").any? { |b| b =~ /#{branch}/i }
|
|
||||||
`git checkout #{branch}`
|
|
||||||
else
|
|
||||||
`git checkout -b #{branch}`
|
|
||||||
end
|
|
||||||
|
|
||||||
`git add -A`
|
|
||||||
`git commit --allow-empty -am 'Automated commit at #{Time.now.utc} by #{Middleman::Deploy::PACKAGE} #{Middleman::Deploy::VERSION}'`
|
|
||||||
`git push -f origin #{branch}`
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def deploy_ftp
|
|
||||||
require 'net/ftp'
|
|
||||||
require 'ptools'
|
|
||||||
|
|
||||||
host = self.deploy_options.host
|
|
||||||
user = self.deploy_options.user
|
|
||||||
pass = self.deploy_options.password
|
|
||||||
path = self.deploy_options.path
|
|
||||||
|
|
||||||
puts "## Deploying via ftp to #{user}@#{host}:#{path}"
|
|
||||||
|
|
||||||
ftp = Net::FTP.new(host)
|
|
||||||
ftp.login(user, pass)
|
|
||||||
ftp.chdir(path)
|
|
||||||
ftp.passive = true
|
|
||||||
|
|
||||||
Dir.chdir(self.inst.build_dir) do
|
|
||||||
files = Dir.glob('**/*', File::FNM_DOTMATCH)
|
|
||||||
files.reject { |a| a =~ Regexp.new('\.$') }.each do |f|
|
|
||||||
if File.directory?(f)
|
|
||||||
begin
|
|
||||||
ftp.mkdir(f)
|
|
||||||
puts "Created directory #{f}"
|
|
||||||
rescue
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if File.binary?(f)
|
|
||||||
ftp.putbinaryfile(f, f)
|
|
||||||
else
|
|
||||||
ftp.puttextfile(f, f)
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
reply = e.message
|
|
||||||
err_code = reply[0,3].to_i
|
|
||||||
if err_code == 550
|
|
||||||
if File.binary?(f)
|
|
||||||
ftp.putbinaryfile(f, f)
|
|
||||||
else
|
|
||||||
ftp.puttextfile(f, f)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
puts "Copied #{f}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ftp.close
|
|
||||||
end
|
|
||||||
|
|
||||||
def deploy_sftp
|
|
||||||
require 'net/sftp'
|
|
||||||
require 'ptools'
|
|
||||||
|
|
||||||
host = self.deploy_options.host
|
|
||||||
user = self.deploy_options.user
|
|
||||||
pass = self.deploy_options.password
|
|
||||||
path = self.deploy_options.path
|
|
||||||
|
|
||||||
puts "## Deploying via sftp to #{user}@#{host}:#{path}"
|
|
||||||
|
|
||||||
Net::SFTP.start(host, user, :password => pass) do |sftp|
|
|
||||||
sftp.mkdir(path)
|
|
||||||
Dir.chdir(self.inst.build_dir) do
|
|
||||||
files = Dir.glob('**/*', File::FNM_DOTMATCH)
|
|
||||||
files.reject { |a| a =~ Regexp.new('\.$') }.each do |f|
|
|
||||||
if File.directory?(f)
|
|
||||||
begin
|
|
||||||
sftp.mkdir("#{path}/#{f}")
|
|
||||||
puts "Created directory #{f}"
|
|
||||||
rescue
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
sftp.upload(f, "#{path}/#{f}")
|
|
||||||
rescue Exception => e
|
|
||||||
reply = e.message
|
|
||||||
err_code = reply[0,3].to_i
|
|
||||||
if err_code == 550
|
|
||||||
sftp.upload(f, "#{path}/#{f}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
puts "Copied #{f}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Alias "d" to "deploy"
|
# Add to CLI
|
||||||
Base.map({ "d" => "deploy" })
|
Base.register(Middleman::Cli::Deploy, 'deploy', 'deploy [options]', Middleman::Deploy::TAGLINE)
|
||||||
|
|
||||||
|
# Alias "d" to "deploy"
|
||||||
|
Base.map('d' => 'deploy')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,20 +1,35 @@
|
||||||
# Require core library
|
# Require core library
|
||||||
require "middleman-core"
|
require 'middleman-core'
|
||||||
|
|
||||||
# Extension namespace
|
# Extension namespace
|
||||||
module Middleman
|
module Middleman
|
||||||
module Deploy
|
module Deploy
|
||||||
|
@options
|
||||||
class Options < Struct.new(:whatisthis, :method, :host, :port, :user, :password, :path, :clean, :remote, :branch, :build_before); end
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
attr_reader :options
|
||||||
|
|
||||||
def options
|
attr_writer :options
|
||||||
@@options
|
end
|
||||||
end
|
|
||||||
|
class Extension < Extension
|
||||||
|
option :deploy_method, nil
|
||||||
|
option :host, nil
|
||||||
|
option :port, nil
|
||||||
|
option :user, nil
|
||||||
|
option :password, nil
|
||||||
|
option :path, nil
|
||||||
|
option :clean, nil
|
||||||
|
option :remote, nil
|
||||||
|
option :branch, nil
|
||||||
|
option :strategy, nil
|
||||||
|
option :build_before, nil
|
||||||
|
option :flags, nil
|
||||||
|
option :commit_message, nil
|
||||||
|
|
||||||
|
def initialize(app, options_hash = {}, &block)
|
||||||
|
super
|
||||||
|
|
||||||
def registered(app, options_hash={}, &block)
|
|
||||||
options = Options.new(options_hash)
|
|
||||||
yield options if block_given?
|
yield options if block_given?
|
||||||
|
|
||||||
# Default options for the rsync method.
|
# Default options for the rsync method.
|
||||||
|
@ -22,25 +37,17 @@ module Middleman
|
||||||
options.clean ||= false
|
options.clean ||= false
|
||||||
|
|
||||||
# Default options for the git method.
|
# Default options for the git method.
|
||||||
options.remote ||= "origin"
|
options.remote ||= 'origin'
|
||||||
options.branch ||= "gh-pages"
|
options.branch ||= 'gh-pages'
|
||||||
|
options.strategy ||= :force_push
|
||||||
|
options.commit_message ||= nil
|
||||||
|
|
||||||
options.build_before ||= false
|
options.build_before ||= false
|
||||||
|
|
||||||
@@options = options
|
|
||||||
|
|
||||||
app.send :include, Helpers
|
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :included :registered
|
def after_configuration
|
||||||
|
::Middleman::Deploy.options = options
|
||||||
end
|
|
||||||
|
|
||||||
module Helpers
|
|
||||||
def options
|
|
||||||
::Middleman::Deploy.options
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
5
lib/middleman-deploy/methods.rb
Normal file
5
lib/middleman-deploy/methods.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'middleman-deploy/methods/base'
|
||||||
|
require 'middleman-deploy/methods/ftp'
|
||||||
|
require 'middleman-deploy/methods/git'
|
||||||
|
require 'middleman-deploy/methods/rsync'
|
||||||
|
require 'middleman-deploy/methods/sftp'
|
22
lib/middleman-deploy/methods/base.rb
Normal file
22
lib/middleman-deploy/methods/base.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Methods
|
||||||
|
class Base
|
||||||
|
attr_reader :options, :server_instance
|
||||||
|
|
||||||
|
def initialize(server_instance, options = {})
|
||||||
|
@options = options
|
||||||
|
@server_instance = server_instance
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_dir
|
||||||
|
server_instance.config.setting(:build_dir).value
|
||||||
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
fail NotImplementedError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
86
lib/middleman-deploy/methods/ftp.rb
Normal file
86
lib/middleman-deploy/methods/ftp.rb
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
require 'net/ftp'
|
||||||
|
require 'ptools'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Methods
|
||||||
|
class Ftp < Base
|
||||||
|
attr_reader :host, :port, :pass, :path, :user
|
||||||
|
|
||||||
|
def initialize(server_instance, options = {})
|
||||||
|
super(server_instance, options)
|
||||||
|
|
||||||
|
@host = self.options.host
|
||||||
|
@user = self.options.user
|
||||||
|
@pass = self.options.password
|
||||||
|
@path = self.options.path
|
||||||
|
@port = self.options.port
|
||||||
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
puts "## Deploying via ftp to #{user}@#{host}:#{path}"
|
||||||
|
|
||||||
|
ftp = open_connection
|
||||||
|
|
||||||
|
Dir.chdir(build_dir) do
|
||||||
|
filtered_files.each do |filename|
|
||||||
|
if File.directory?(filename)
|
||||||
|
upload_directory(ftp, filename)
|
||||||
|
else
|
||||||
|
upload_binary(ftp, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ftp.close
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def filtered_files
|
||||||
|
files = Dir.glob('**/*', File::FNM_DOTMATCH)
|
||||||
|
|
||||||
|
files.reject { |filename| filename =~ Regexp.new('\.$') }
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_exception(exception, ftp, filename)
|
||||||
|
reply = exception.message
|
||||||
|
err_code = reply[0, 3].to_i
|
||||||
|
|
||||||
|
if err_code == 550
|
||||||
|
if File.binary?(filename)
|
||||||
|
ftp.putbinaryfile(filename, filename)
|
||||||
|
else
|
||||||
|
ftp.puttextfile(filename, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_connection
|
||||||
|
ftp = Net::FTP.new(host)
|
||||||
|
ftp.login(user, pass)
|
||||||
|
ftp.chdir(path)
|
||||||
|
ftp.passive = true
|
||||||
|
|
||||||
|
ftp
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_binary(ftp, filename)
|
||||||
|
begin
|
||||||
|
ftp.putbinaryfile(filename, filename)
|
||||||
|
rescue Exception => exception
|
||||||
|
handle_exception(exception, ftp, filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Copied #{filename}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_directory(ftp, filename)
|
||||||
|
ftp.mkdir(filename)
|
||||||
|
puts "Created directory #{filename}"
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
lib/middleman-deploy/methods/git.rb
Normal file
17
lib/middleman-deploy/methods/git.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Methods
|
||||||
|
class Git < Base
|
||||||
|
def process
|
||||||
|
puts "## Deploying via git to remote=\"#{options.remote}\" and branch=\"#{options.branch}\""
|
||||||
|
|
||||||
|
camelized_strategy = options.strategy.to_s.split('_').map(&:capitalize).join
|
||||||
|
strategy_class_name = "Middleman::Deploy::Strategies::Git::#{camelized_strategy}"
|
||||||
|
strategy_instance = strategy_class_name.constantize.new(build_dir, options.remote, options.branch, options.commit_message)
|
||||||
|
|
||||||
|
strategy_instance.process
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
lib/middleman-deploy/methods/rsync.rb
Normal file
34
lib/middleman-deploy/methods/rsync.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Methods
|
||||||
|
class Rsync < Base
|
||||||
|
attr_reader :clean, :flags, :host, :path, :port, :user
|
||||||
|
|
||||||
|
def initialize(server_instance, options = {})
|
||||||
|
super(server_instance, options)
|
||||||
|
|
||||||
|
@clean = self.options.clean
|
||||||
|
@flags = self.options.flags
|
||||||
|
@host = self.options.host
|
||||||
|
@path = self.options.path
|
||||||
|
@port = self.options.port
|
||||||
|
@user = self.options.user
|
||||||
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
# Append "@" to user if provided.
|
||||||
|
user = "#{self.user}@" if user && !user.empty?
|
||||||
|
|
||||||
|
dest_url = "#{user}#{host}:#{path}"
|
||||||
|
flags = self.flags || '-avz'
|
||||||
|
command = "rsync #{flags} '-e ssh -p #{port}' #{build_dir}/ #{dest_url}"
|
||||||
|
|
||||||
|
command += ' --delete' if clean
|
||||||
|
|
||||||
|
puts "## Deploying via rsync to #{dest_url} port=#{port}"
|
||||||
|
exec command
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
60
lib/middleman-deploy/methods/sftp.rb
Normal file
60
lib/middleman-deploy/methods/sftp.rb
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
require 'net/sftp'
|
||||||
|
require 'ptools'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Methods
|
||||||
|
class Sftp < Ftp
|
||||||
|
def process
|
||||||
|
puts "## Deploying via sftp to #{user}@#{host}:#{path}"
|
||||||
|
|
||||||
|
# `nil` is a valid value for user and/or pass.
|
||||||
|
Net::SFTP.start(host, user, password: pass, port: port) do |sftp|
|
||||||
|
sftp.mkdir(path)
|
||||||
|
|
||||||
|
Dir.chdir(build_dir) do
|
||||||
|
filtered_files.each do |filename|
|
||||||
|
if File.directory?(filename)
|
||||||
|
upload_directory(sftp, filename)
|
||||||
|
else
|
||||||
|
upload_file(sftp, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def handle_exception(exception, filename, file_path)
|
||||||
|
reply = exception.message
|
||||||
|
err_code = reply[0, 3].to_i
|
||||||
|
|
||||||
|
sftp.upload(filename, file_path) if err_code == 550
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_directory(sftp, filename)
|
||||||
|
file_path = "#{path}/#{filename}"
|
||||||
|
|
||||||
|
begin
|
||||||
|
sftp.mkdir(file_path)
|
||||||
|
puts "Created directory #{filename}"
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_file(sftp, filename)
|
||||||
|
file_path = "#{path}/#{filename}"
|
||||||
|
|
||||||
|
begin
|
||||||
|
sftp.upload(filename, file_path)
|
||||||
|
rescue Exception => exception
|
||||||
|
handle_exception(exception, filename, file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Copied #{filename}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,7 +1,64 @@
|
||||||
module Middleman
|
module Middleman
|
||||||
module Deploy
|
module Deploy
|
||||||
PACKAGE = "middleman-deploy"
|
PACKAGE = 'middleman-deploy'
|
||||||
VERSION = "0.1.2"
|
VERSION = '2.0.0-alpha'
|
||||||
TAGLINE = "Deploy a middleman built site over rsync, ftp, sftp, or git (e.g. gh-pages on github)."
|
TAGLINE = 'Deploy a middleman built site over rsync, ftp, sftp, or git (e.g. gh-pages on github).'
|
||||||
|
README = %{
|
||||||
|
You should follow one of the four examples below to setup the deploy
|
||||||
|
extension in config.rb.
|
||||||
|
|
||||||
|
# To deploy the build directory to a remote host via rsync:
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.method = :rsync
|
||||||
|
# host and path *must* be set
|
||||||
|
deploy.host = "www.example.com"
|
||||||
|
deploy.path = "/srv/www/site"
|
||||||
|
# user is optional (no default)
|
||||||
|
deploy.user = "tvaughan"
|
||||||
|
# port is optional (default is 22)
|
||||||
|
deploy.port = 5309
|
||||||
|
# clean is optional (default is false)
|
||||||
|
deploy.clean = true
|
||||||
|
# flags is optional (default is -avze)
|
||||||
|
deploy.flags = "-rltgoDvzO --no-p --del -e"
|
||||||
|
end
|
||||||
|
|
||||||
|
# To deploy to a remote branch via git (e.g. gh-pages on github):
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.method = :git
|
||||||
|
# remote is optional (default is "origin")
|
||||||
|
# run `git remote -v` to see a list of possible remotes
|
||||||
|
deploy.remote = "some-other-remote-name"
|
||||||
|
|
||||||
|
# branch is optional (default is "gh-pages")
|
||||||
|
# run `git branch -a` to see a list of possible branches
|
||||||
|
deploy.branch = "some-other-branch-name"
|
||||||
|
|
||||||
|
# strategy is optional (default is :force_push)
|
||||||
|
deploy.strategy = :submodule
|
||||||
|
end
|
||||||
|
|
||||||
|
# To deploy the build directory to a remote host via ftp:
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.method = :ftp
|
||||||
|
# host, user, passwword and path *must* be set
|
||||||
|
deploy.host = "ftp.example.com"
|
||||||
|
deploy.path = "/srv/www/site"
|
||||||
|
deploy.user = "tvaughan"
|
||||||
|
deploy.password = "secret"
|
||||||
|
end
|
||||||
|
|
||||||
|
# To deploy the build directory to a remote host via sftp:
|
||||||
|
activate :deploy do |deploy|
|
||||||
|
deploy.method = :sftp
|
||||||
|
# host, user, passwword and path *must* be set
|
||||||
|
deploy.host = "sftp.example.com"
|
||||||
|
deploy.port = 22
|
||||||
|
deploy.path = "/srv/www/site"
|
||||||
|
# user is optional (no default)
|
||||||
|
deploy.user = "tvaughan"
|
||||||
|
# password is optional (no default)
|
||||||
|
deploy.password = "secret"
|
||||||
|
end}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
3
lib/middleman-deploy/strategies.rb
Normal file
3
lib/middleman-deploy/strategies.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
require 'middleman-deploy/strategies/git/base'
|
||||||
|
require 'middleman-deploy/strategies/git/force_push'
|
||||||
|
require 'middleman-deploy/strategies/git/submodule'
|
56
lib/middleman-deploy/strategies/git/base.rb
Normal file
56
lib/middleman-deploy/strategies/git/base.rb
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Strategies
|
||||||
|
module Git
|
||||||
|
class Base
|
||||||
|
attr_accessor :branch, :build_dir, :remote, :commit_message, :user_name, :user_email
|
||||||
|
|
||||||
|
def initialize(build_dir, remote, branch, commit_message)
|
||||||
|
self.branch = branch
|
||||||
|
self.build_dir = build_dir
|
||||||
|
self.remote = remote
|
||||||
|
self.commit_message = commit_message
|
||||||
|
self.user_name = `git config --get user.name`
|
||||||
|
self.user_email = `git config --get user.email`
|
||||||
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
fail NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def add_signature_to_commit_message(base_message)
|
||||||
|
signature = "#{Middleman::Deploy::PACKAGE} #{Middleman::Deploy::VERSION}"
|
||||||
|
time = "#{Time.now.utc}"
|
||||||
|
|
||||||
|
"#{base_message} at #{time} by #{signature}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def checkout_branch
|
||||||
|
# if there is a branch with that name, switch to it, otherwise create a new one and switch to it
|
||||||
|
if `git branch`.split("\n").any? { |b| b =~ /#{branch}/i }
|
||||||
|
`git checkout #{branch}`
|
||||||
|
else
|
||||||
|
`git checkout -b #{branch}`
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def commit_branch(options = '')
|
||||||
|
message = commit_message ? commit_message : add_signature_to_commit_message('Automated commit')
|
||||||
|
|
||||||
|
run_or_fail('git add -A')
|
||||||
|
run_or_fail("git commit --allow-empty -am \"#{message}\"")
|
||||||
|
run_or_fail("git push #{options} origin #{branch}")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def run_or_fail(command)
|
||||||
|
system(command) || fail("ERROR running: #{command}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
58
lib/middleman-deploy/strategies/git/force_push.rb
Normal file
58
lib/middleman-deploy/strategies/git/force_push.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Strategies
|
||||||
|
module Git
|
||||||
|
class ForcePush < Base
|
||||||
|
def process
|
||||||
|
Dir.chdir(build_dir) do
|
||||||
|
add_remote_url
|
||||||
|
checkout_branch
|
||||||
|
commit_branch('-f')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def add_remote_url
|
||||||
|
url = get_remote_url
|
||||||
|
|
||||||
|
unless File.exist?('.git')
|
||||||
|
`git init`
|
||||||
|
`git remote add origin #{url}`
|
||||||
|
`git config user.name "#{user_name}"`
|
||||||
|
`git config user.email "#{user_email}"`
|
||||||
|
else
|
||||||
|
# check if the remote repo has changed
|
||||||
|
unless url == `git config --get remote.origin.url`.chop
|
||||||
|
`git remote rm origin`
|
||||||
|
`git remote add origin #{url}`
|
||||||
|
end
|
||||||
|
# check if the user name has changed
|
||||||
|
`git config user.name "#{user_name}"` unless user_name == `git config --get user.name`
|
||||||
|
# check if the user email has changed
|
||||||
|
`git config user.email "#{user_email}"` unless user_email == `git config --get user.email`
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_remote_url
|
||||||
|
remote = self.remote
|
||||||
|
url = remote
|
||||||
|
|
||||||
|
# check if remote is not a git url
|
||||||
|
unless remote =~ /\.git$/
|
||||||
|
url = `git config --get remote.#{url}.url`.chop
|
||||||
|
end
|
||||||
|
|
||||||
|
# if the remote name doesn't exist in the main repo
|
||||||
|
if url == ''
|
||||||
|
puts "Can't deploy! Please add a remote with the name '#{remote}' to your repo."
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
42
lib/middleman-deploy/strategies/git/submodule.rb
Normal file
42
lib/middleman-deploy/strategies/git/submodule.rb
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
module Middleman
|
||||||
|
module Deploy
|
||||||
|
module Strategies
|
||||||
|
module Git
|
||||||
|
class Submodule < Base
|
||||||
|
def process
|
||||||
|
Dir.chdir(build_dir) do
|
||||||
|
checkout_branch
|
||||||
|
pull_submodule
|
||||||
|
commit_branch
|
||||||
|
end
|
||||||
|
|
||||||
|
commit_submodule
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def commit_submodule
|
||||||
|
current_branch = `git rev-parse --abbrev-ref HEAD`
|
||||||
|
message = add_signature_to_commit_message('Deployed')
|
||||||
|
|
||||||
|
`git add #{build_dir}`
|
||||||
|
`git commit --allow-empty -m "#{message}"`
|
||||||
|
`git push origin #{current_branch}`
|
||||||
|
end
|
||||||
|
|
||||||
|
def pull_submodule
|
||||||
|
`git fetch`
|
||||||
|
`git stash`
|
||||||
|
`git rebase #{remote}/#{branch}`
|
||||||
|
`git stash pop`
|
||||||
|
|
||||||
|
if $CHILD_STATUS.exitstatus == 1
|
||||||
|
puts "Can't deploy! Please resolve conflicts. Then process to manual commit and push on #{branch} branch."
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1 +1 @@
|
||||||
require "middleman-deploy"
|
require 'middleman-deploy'
|
||||||
|
|
|
@ -1,27 +1,32 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# coding: utf-8
|
||||||
$:.push File.expand_path("../lib", __FILE__)
|
lib = File.expand_path('../lib', __FILE__)
|
||||||
require "middleman-deploy/pkg-info"
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||||
|
require 'middleman-deploy/pkg-info'
|
||||||
|
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |spec|
|
||||||
s.name = Middleman::Deploy::PACKAGE
|
spec.name = Middleman::Deploy::PACKAGE
|
||||||
s.version = Middleman::Deploy::VERSION
|
spec.version = Middleman::Deploy::VERSION
|
||||||
s.platform = Gem::Platform::RUBY
|
spec.authors = ['Tom Vaughan', 'Karl Freeman']
|
||||||
s.authors = ["Tom Vaughan"]
|
spec.email = ['thomas.david.vaughan@gmail.com', 'karlfreeman@gmail.com']
|
||||||
s.email = ["thomas.david.vaughan@gmail.com"]
|
spec.summary = Middleman::Deploy::TAGLINE
|
||||||
s.homepage = "http://tvaughan.github.io/middleman-deploy/"
|
spec.description = Middleman::Deploy::TAGLINE
|
||||||
s.summary = Middleman::Deploy::TAGLINE
|
spec.homepage = 'https://github.com/karlfreeman/middleman-deploy'
|
||||||
s.description = Middleman::Deploy::TAGLINE
|
spec.license = 'MIT'
|
||||||
s.license = "MIT"
|
|
||||||
|
|
||||||
s.files = `git ls-files`.split("\n")
|
spec.files = `git ls-files -z`.split("\x0")
|
||||||
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||||
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
||||||
s.require_paths = ["lib"]
|
spec.require_paths = ['lib']
|
||||||
|
spec.required_ruby_version = '>= 1.9.3'
|
||||||
|
|
||||||
# The version of middleman-core your extension depends on
|
spec.add_dependency 'middleman-core', '>= 3.2'
|
||||||
s.add_runtime_dependency("middleman-core", [">= 3.0.0"])
|
spec.add_dependency 'ptools'
|
||||||
|
spec.add_dependency 'net-sftp'
|
||||||
|
|
||||||
# Additional dependencies
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
||||||
s.add_runtime_dependency("ptools")
|
spec.add_development_dependency 'rake', '~> 10.0'
|
||||||
s.add_runtime_dependency("net-sftp")
|
spec.add_development_dependency 'kramdown', '>= 0.14'
|
||||||
|
spec.add_development_dependency 'rubocop', '~> 0.19'
|
||||||
|
spec.add_development_dependency 'pry'
|
||||||
|
spec.add_development_dependency 'yard'
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue