This repository has been archived by the owner on Sep 6, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor of initial config clone and server bootup
Finally a clean `config.ru` and a clean `fastlane_app` 馃憤
- Loading branch information
Showing
12 changed files
with
261 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
module FastlaneCI | ||
class Launch | ||
def self.take_off | ||
verify_dependencies | ||
load_dot_env | ||
verify_env_variables | ||
setup_threads | ||
require_fastlane_ci | ||
check_for_existing_setup | ||
prepare_server | ||
# launch_workers | ||
end | ||
|
||
def self.require_fastlane_ci | ||
# before running, call `bundle install --path vendor/bundle` | ||
# this isolates the gems for bundler | ||
require "./fastlane_app" | ||
|
||
# allow use of `require` for all things under `shared`, helps with some cycle issues | ||
$LOAD_PATH << "shared" | ||
end | ||
|
||
def self.load_dot_env | ||
return unless File.exist?(".keys") | ||
require "dotenv" | ||
Dotenv.load(".keys") | ||
end | ||
|
||
def self.verify_dependencies | ||
begin | ||
require "openssl" | ||
rescue LoadError | ||
warn("Error: no such file to load -- openssl. Make sure you have openssl installed") | ||
exit(1) | ||
end | ||
end | ||
|
||
def self.verify_env_variables | ||
# Don't even try to run without having those | ||
if ENV["FASTLANE_CI_ENCRYPTION_KEY"].nil? | ||
warn("Error: unable to decrypt sensitive data without environment variable `FASTLANE_CI_ENCRYPTION_KEY` set") | ||
exit(1) | ||
end | ||
|
||
if ENV["FASTLANE_CI_USER"].nil? || ENV["FASTLANE_CI_PASSWORD"].nil? | ||
warn("Error: ensure you have your `FASTLANE_CI_USER` and `FASTLANE_CI_PASSWORD`environment variables set") | ||
exit(1) | ||
end | ||
|
||
if ENV["FASTLANE_CI_REPO_URL"].nil? | ||
warn("Error: ensure you have your `FASTLANE_CI_REPO_URL` environment variable set") | ||
exit(1) | ||
end | ||
end | ||
|
||
def self.setup_threads | ||
if ENV["RACK_ENV"] == "development" | ||
puts("development mode, aborting on any thread exceptions") | ||
Thread.abort_on_exception = true | ||
end | ||
end | ||
|
||
# Check if fastlane.ci already ran on this machine | ||
# and with that, have the initial `users.json`, etc. | ||
# If not, this is where we do the initial clone | ||
def self.check_for_existing_setup | ||
# TODO: check if it already exists | ||
unless self.ci_config_repo.exists? | ||
self.trigger_initial_ci_setup | ||
end | ||
|
||
Services.ci_config_repo = self.ci_config_repo | ||
end | ||
|
||
def self.ci_config_repo | ||
# Setup the fastlane.ci GitRepoConfig | ||
@_ci_config_repo ||= GitRepoConfig.new( | ||
id: "fastlane-ci-config", | ||
git_url: ENV["FASTLANE_CI_REPO_URL"], | ||
description: "Contains the fastlane.ci configuration", | ||
name: "fastlane ci", | ||
hidden: true | ||
) | ||
end | ||
|
||
# We can't actually launch the server here | ||
# as it seems like it has to happen in `config.ru` | ||
def self.prepare_server | ||
# require all controllers | ||
require_relative "features/dashboard/dashboard_controller" | ||
require_relative "features/login/login_controller" | ||
require_relative "features/project/project_controller" | ||
|
||
# Load up all the available controllers | ||
FastlaneCI::FastlaneApp.use(FastlaneCI::DashboardController) | ||
FastlaneCI::FastlaneApp.use(FastlaneCI::LoginController) | ||
FastlaneCI::FastlaneApp.use(FastlaneCI::ProjectController) | ||
end | ||
|
||
def self.launch_workers | ||
# Iterate through all provider credentials and their projects and start a worker for each project | ||
number_of_workers_started = 0 | ||
Services.ci_user.provider_credentials.each do |provider_credential| | ||
projects = Services.config_service.projects(provider_credential: provider_credential) | ||
projects.each do |project| | ||
Services.worker_service.start_worker_for_provider_credential_and_config( | ||
project: project, | ||
provider_credential: provider_credential | ||
) | ||
number_of_workers_started += 1 | ||
end | ||
end | ||
|
||
# TODO: use logger if possible | ||
puts("Seems like no workers were started to monitor your projects") if number_of_workers_started == 0 | ||
|
||
# Initialize the workers | ||
# For now, we're not using a fancy framework that adds multiple heavy dependencies | ||
# including a database, etc. | ||
FastlaneCI::RefreshConfigDataSourcesWorker.new | ||
end | ||
|
||
# Verify that fastlane.ci is already set up on this machine. | ||
# If that's not the case, we have to make sure to trigger the initial clone | ||
def self.trigger_initial_ci_setup | ||
puts "No config repo cloned yet, doing that now" # TODO: use logger if possible | ||
|
||
# This happens on the first launch of CI | ||
# We don't have access to the config directory yet | ||
# So we'll use ENV variables that are used for the initial clone only | ||
# | ||
# Long term, we'll have a nice onboarding flow, where you can enter those credentials | ||
# as part of a web UI. But for containers (e.g. Google Cloud App Engine) | ||
# we'll have to support ENV variables also, for the initial clone, so that's the code below | ||
# Clone the repo, and login the user | ||
provider_credential = GitHubProviderCredential.new(email: ENV["FASTLANE_CI_INITIAL_CLONE_EMAIL"], | ||
api_token: ENV["FASTLANE_CI_INITIAL_CLONE_API_TOKEN"]) | ||
# Trigger the initial clone | ||
FastlaneCI::JSONProjectDataSource.new( | ||
git_repo_config: ci_config_repo, | ||
provider_credential: provider_credential | ||
) | ||
puts "Successfully did the initial clone on this machine" | ||
rescue StandardError => ex | ||
puts("Something went wrong on the initial clone") | ||
|
||
if ENV["FASTLANE_CI_INITIAL_CLONE_API_TOKEN"].to_s.length == 0 || ENV["FASTLANE_CI_INITIAL_CLONE_EMAIL"].to_s.length == 0 | ||
puts("Make sure to provide your `FASTLANE_CI_INITIAL_CLONE_EMAIL` and `FASTLANE_CI_INITIAL_CLONE_API_TOKEN` ENV variables") | ||
end | ||
|
||
raise ex | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.