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.



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
54
# File 'lib/dpl/provider/pages.rb', line 28

def initialize(context, options)
  super

  @build_dir = File.join(src_dir, options[:local_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[: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



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

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

#apiObject

Borrowed from Releases provider



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

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



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

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



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

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

#fqdnObject



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

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

#gh_remote_urlObject



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

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

#gh_tokenObject



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

def gh_token
  @gh_token ||= option(:github_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



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

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"
    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



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

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

#needs_key?Boolean

Returns:

  • (Boolean)


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

def needs_key?
  false
end


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

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 -r --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



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

def setup_auth
  user.
end

#slugObject



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

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

#src_dirObject



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

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

#userObject



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

def user
  @user ||= api.user
end

#verboseObject



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

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