Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mount migration tool #2544

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "vendor/emojis"]
path = vendor/emojis
url = https://github.com/buildkite/emojis.git
[submodule "vendor/migration"]
path = vendor/migration
url = https://github.com/buildkite/migration
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,5 @@ end
group :test do
gem "buildkite-test_collector"
end

gem "parslet"
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ GEM
nokogiri (1.15.2)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
parslet (2.0.0)
pry (0.14.1)
coderay (~> 1.1)
method_source (~> 1.0)
Expand Down Expand Up @@ -175,6 +176,7 @@ DEPENDENCIES
graphql-client
lograge
matrix
parslet
pry
puma
railties (~> 6.0)
Expand Down
20 changes: 20 additions & 0 deletions app/controllers/migration_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class MigrationController < ApplicationController
skip_forgery_protection

def show
@nav = default_nav

render template: "migrate", layout: "homepage"
end

def migrate
# Some request path rewriting for the compat server to slot in.
request.env["REQUEST_PATH"] = "/"
request.env["REQUEST_URI"] = "/"
request.env["PATH_INFO"] = "/"

res = BK::Compat::Server.new.call(request.env)

render body: res[2].string, status: res[0], content_type: res[1]["content-type"]
end
end
7 changes: 1 addition & 6 deletions app/models/nav.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@ def current_item_root(request)

# Returns the current nav item
def current_item(request)
return nil if request.path == "/docs"

item = route_map[request.path.sub("/docs/", "")]
raise ActionController::RoutingError.new("Missing navigation for #{request.path}") unless item

item
route_map[request.path.sub("/docs/", "")]
end

# Returns a hash of routes, indexed by path
Expand Down
175 changes: 175 additions & 0 deletions app/views/migrate.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Helvetica, sans-serif;
padding: 0;
margin: 0;
}
.flex {
display: flex;
}
.flex-column {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
.flex-auto {
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
min-width: 0;
min-height: 0;
}
.items-center {
align-items: center;
}
.items-stretch {
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
}
.justify-center {
justify-content: center;
}
.center {
text-align: center;
}
input[type=submit] {
border-radius: 4px;
background-color: #14cc80;
border: 1px solid transparent;
color: white;
font-size: 1em;
padding: .75em 1em;
line-height: 1.2;
font-weight: bold;
font-family: inherit;
cursor: pointer;
}
input[type=submit]:hover {
box-shadow: inset 0 0 0 20rem rgba(0, 0, 0, .0625);
}
input[type=submit]:disabled {
opacity: 0.5;
}
textarea {
display: block;
width: 100%;
padding: 15px;
font-size: 12px;
font-family: "SFMono-Regular", Monaco, Menlo, Consolas, "Liberation Mono", Courier, monospace;
line-height: 1.42857143;
color: #555555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: .3em;
resize: none;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);

/* disable iOS' extra inner shadows */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none
}
textarea:focus {
border-color: #888;
outline: 0;
}
textarea[readonly] {
background: #f9fafb;
}
.error {
background: #ff000044 !important;
}
</style>


<div class="flex items-stretch justify-center" style="min-height: 100%">
<form onSubmit="return transform(event)" class="flex items-stretch center flex-column" style="width: 100%; padding: 5%;">
<div class="flex flex-auto" style="margin-bottom: 20px;">
<textarea rows="20" style="width: 50%; margin-right: 20px" placeholder="👋 Paste or drag a config file here!" id="config" class="flex-auto"></textarea>
<textarea rows="20" style="width: 50%" readonly="true" id="results" placeholder="👈 Look over there" class="flex-auto"></textarea>
</div>
<div>
<input type="submit" value="Buildkite-ify!" id="button" />
</div>
</form>
</div>

<script>
function transform() {
var button = document.getElementById("button");

var configTextarea = document.getElementById("config");
var formData = new FormData();
formData.append("file", new Blob([configTextarea.value], { type: "text/plain" }));

button.disabled = true;

var resultsTextarea = document.getElementById("results");

fetch("<%= migrate_url %>", {
method: "POST",
credentials: 'same-origin',
body: formData
}).then(function(response) {
button.disabled = false;
if (!response.ok) {
resultsTextarea.classList.add('error')
} else {
resultsTextarea.classList.remove('error')
}
return response;
}).then(function(response) {
response.text().then(function(text) {
resultsTextarea.value = text;
});
}).catch((function(error) {
alert(error.message);
resultsTextarea.value = '';
}));

return false;
}

function handleFormSubmit() {
event.preventDefault();

transform();
}

function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();

var file = evt.dataTransfer.files[0];

if (file) {
if (file.type == "application/x-yaml") {
var reader = new FileReader();

reader.onload = function(e) {
document.getElementById("config").value = e.target.result;
transform();
};

reader.readAsText(file);
} else {
alert("Only YAML files are supported - you uploaded a: " + file.type);
}
}
}

function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}

// Setup the dnd listeners.
var dropZone = document.body;
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
</script>
2 changes: 2 additions & 0 deletions config/initializers/migration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require Rails.root.join('vendor/migration/app/lib/bk/compat').to_s
require Rails.root.join('vendor/migration/app/lib/bk/compat/server').to_s
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@
# Homepage
get "/docs" => "pages#index", as: :home_page

# Hosted migration/transform tool
get "/docs/migrate" => "migration#show"
post "/docs/migrate" => "migration#migrate", as: :migrate

# All other standard docs pages
get "/docs/*path" => "pages#show", as: :docs_page

Expand Down
1 change: 1 addition & 0 deletions vendor/migration
Submodule migration added at c9c421