Class: DPL::Provider::Pages

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

Instance Attribute Summary

Attributes inherited from DPL::Provider

#context, #options

Instance Method Summary collapse

Methods inherited from DPL::Provider

apt_get, #check_app, #cleanup, #commit_msg, context, #create_key, #default_text_charset, #default_text_charset?, #deploy, deprecated, #detect_encoding?, #encoding_for, #error, experimental, #log, new, npm_g, #option, pip, requires, #run, #setup_git_credentials, #setup_git_ssh, #sha, shell, #uncleanup, #user_agent, #warn

Constructor Details

#initialize(context, options) ⇒ Pages

Returns a new instance of Pages.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/dpl/provider/pages.rb', line 33

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'
  @gh_token = option(:github_token)
  @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"
  @gh_remote_url = "https://#{@gh_token}@#{@gh_ref}"
  @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

#github_commitObject



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

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



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

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



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

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



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

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
# 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"
    Dir.mkdir(target_dir)  # Restore dir destroyed by failed `git clone`
    github_init(target_dir)
  end
end

#identify_preferred_committerObject



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

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



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

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



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