Class: DPL::Provider::Pages

Inherits:
DPL::Provider show all
Defined in:
lib/dpl/provider/pages.rb

Instance Method Summary collapse

Constructor Details

#initialize(context, options) ⇒ Pages

Returns a new instance of Pages.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/dpl/provider/pages.rb', line 27

def initialize(context, options)
  super

  @build_dir = File.absolute_path(options[:local_dir] || '.', src_dir)
  print_step "The target dir for deployment is '#{@build_dir}'."

  @project_name = options[:project_name] || fqdn || slug
  @target_branch = options[:target_branch] || 'gh-pages'

  @gh_fqdn = fqdn
  @gh_url = options[:url] || options[:github_url] || 'github.com'
  @keep_history = !!keep_history
  @allow_empty_commit = !!allow_empty_commit
  @committer_from_gh = !!committer_from_gh
  @verbose = !!verbose

  @gh_email = options[:email] || '[email protected]'
  @gh_name = "#{options[:name] || 'Deployment Bot'} (from Travis CI)"

  @deployment_file = !!options[:deployment_file]

  @gh_ref = "#{@gh_url}/#{slug}.git"
  @git_push_opts = @keep_history ? '' : ' --force'
  @git_commit_opts = (@allow_empty_commit and @keep_history) ? ' --allow-empty' : ''

  print_step "The repo is configured to use committer user and email." if @committer_from_gh
end

Instance Method Details

#allow_empty_commitObject



83
84
85
# File 'lib/dpl/provider/pages.rb', line 83

def allow_empty_commit
  options.fetch(:allow_empty_commit, false)
end

#apiObject

Borrowed from Releases provider



92
93
94
95
96
97
98
99
100
101
# File 'lib/dpl/provider/pages.rb', line 92

def api  # Borrowed from Releases provider
  error 'gh-token must be provided for Pages provider to work.' unless gh_token

  return @api if @api

  api_opts = { :access_token => gh_token }
  api_opts[:api_endpoint] = @gh_url == 'github.com' ? "https://api.github.com/" : "https://#{@gh_url}/api/v3/"

  @api = Octokit::Client.new(api_opts)
end

#check_authObject



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/dpl/provider/pages.rb', line 111

def check_auth
  setup_auth

  unless api.scopes.include? 'public_repo' or api.scopes.include? 'repo'
    error "Dpl does not have permission to access #{@gh_url} using it. Make sure your token contains the repo or public_repo scope."
  end

  log "Logged in as @#{user.} (#{user.name})"
rescue Octokit::Unauthorized => exc
  error "gh-token is invalid. Details: #{exc}"
end

#committer_from_ghObject



79
80
81
# File 'lib/dpl/provider/pages.rb', line 79

def committer_from_gh
  options.fetch(:committer_from_gh, false)
end

#fqdnObject



63
64
65
# File 'lib/dpl/provider/pages.rb', line 63

def fqdn
  options.fetch(:fqdn) { nil }
end

#gh_remote_urlObject



59
60
61
# File 'lib/dpl/provider/pages.rb', line 59

def gh_remote_url
  @gh_remote_url ||= "https://#{gh_token}@#{@gh_ref}"
end

#gh_tokenObject



55
56
57
# File 'lib/dpl/provider/pages.rb', line 55

def gh_token
  @gh_token ||= option(:github_token, :token)
end

#github_commitObject



171
172
173
174
175
176
177
178
179
# File 'lib/dpl/provider/pages.rb', line 171

def github_commit
  committer_name, _ = identify_preferred_committer
  print_step "Preparing to deploy #{@target_branch} branch to gh-pages (workdir: #{Dir.pwd})"
  context.shell "touch \"deployed at `date` by #{committer_name}\"" if @deployment_file
  context.shell "echo '#{@gh_fqdn}' > CNAME" if @gh_fqdn
  context.shell 'git add -A .'
  context.shell "git commit#{@git_commit_opts} -qm 'Deploy #{@project_name} to #{@gh_ref}:#{@target_branch}'"
  context.shell 'git show --stat-count=10 HEAD'
end

#github_configureObject



164
165
166
167
168
169
# File 'lib/dpl/provider/pages.rb', line 164

def github_configure
  committer_name, committer_email = identify_preferred_committer
  print_step "Configuring git committer to be #{committer_name} <#{committer_email}> (workdir: #{Dir.pwd})"
  context.shell "git config user.email '#{committer_email}'"
  context.shell "git config user.name '#{committer_name}'"
end

#github_deployObject



181
182
183
184
185
186
# File 'lib/dpl/provider/pages.rb', line 181

def github_deploy
  print_step "Doing the git push (workdir: #{Dir.pwd})..."
  unless context.shell "git push#{@git_push_opts} --quiet '#{gh_remote_url}' '#{@target_branch}':'#{@target_branch}' > /dev/null 2>&1"
    error "Couldn't push the build to #{@gh_ref}:#{@target_branch}"
  end
end

#github_init(target_dir) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/dpl/provider/pages.rb', line 147

def github_init(target_dir)
  FileUtils.cd(target_dir, :verbose => true) do
    print_step "Creating a brand new local repo from scratch in dir #{Dir.pwd}..."
    context.shell "git init" or raise 'Could not create new git repo'
    print_step 'Repo created successfully'
    context.shell "git checkout --orphan '#{@target_branch}'" or raise 'Could not create an orphan git branch'
    print_step "An orphan branch #{@target_branch} created successfully"
  end
end

#github_pull_or_init(target_dir) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/dpl/provider/pages.rb', line 131

def github_pull_or_init(target_dir)
  unless @keep_history
    github_init(target_dir)
    return
  end

  print_step "Trying to clone a single branch #{@target_branch} from existing repo..."
  unless context.shell "git clone --quiet --branch='#{@target_branch}' --depth=1 '#{gh_remote_url}' '#{target_dir}' > /dev/null 2>&1"
    # if such branch doesn't exist at remote, init it from scratch
    print_step "Cloning #{@target_branch} branch failed"
    FileUtils.rm_rf(target_dir)
    Dir.mkdir(target_dir)  # Restore dir destroyed by failed `git clone`
    github_init(target_dir)
  end
end

#identify_preferred_committerObject



157
158
159
160
161
162
# File 'lib/dpl/provider/pages.rb', line 157

def identify_preferred_committer
  if @committer_from_gh and gh_token
    return (user.name or @gh_name), (user.email or @gh_email)
  end
  return @gh_name, @gh_email
end

#keep_historyObject



75
76
77
# File 'lib/dpl/provider/pages.rb', line 75

def keep_history
  options.fetch(:keep_history, false)
end

#needs_key?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/dpl/provider/pages.rb', line 123

def needs_key?
  false
end


127
128
129
# File 'lib/dpl/provider/pages.rb', line 127

def print_step(msg)
  log msg if @verbose
end

#push_appObject



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/dpl/provider/pages.rb', line 188

def push_app
  print_step "Starting deployment of #{@target_branch} branch to GitHub Pages..."
  print_step "The deployment is configured to preserve the target branch if it exists on remote" if @keep_history
  Dir.mktmpdir do |tmpdir|
      workdir = "#{tmpdir}/work"
      Dir.mkdir(workdir)
      print_step "Created a temporary work directory #{workdir}"

      github_pull_or_init(workdir)

      FileUtils.cd(workdir, :verbose => true) do
        print_step "Copying #{@build_dir} contents to #{workdir} (workdir: #{Dir.pwd})..."
        context.shell "rsync -rl --exclude .git --delete '#{@build_dir}/' '#{workdir}'" or error "Could not copy #{@build_dir}."

        github_configure
        github_commit
        github_deploy
        context.shell "git status" if @verbose
      end
  end
  print_step "App has been pushed"
end

#setup_authObject



107
108
109
# File 'lib/dpl/provider/pages.rb', line 107

def setup_auth
  user.
end

#slugObject



67
68
69
# File 'lib/dpl/provider/pages.rb', line 67

def slug
  options.fetch(:repo) { context.env['TRAVIS_REPO_SLUG'] }
end

#src_dirObject



71
72
73
# File 'lib/dpl/provider/pages.rb', line 71

def src_dir
  context.env['TRAVIS_BUILD_DIR'] or Dir.pwd
end

#userObject



103
104
105
# File 'lib/dpl/provider/pages.rb', line 103

def user
  @user ||= api.user
end

#verboseObject



87
88
89
90
# File 'lib/dpl/provider/pages.rb', line 87

def verbose
  # Achtung! Never verbosify git, since it may expose user's token.
  options.fetch(:verbose, false)
end