diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bb6d7fc725ff7..760e42d58640c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -30,7 +30,7 @@ Please test your changes before submitting them to us!
### Manual testing
-We support recent versions of Firefox, Chrome, Internet Explorer, Edge, iOS Safari and the Android browsers ([full list of supported browsers and versions](https://support.code.org/hc/en-us/articles/202591743)). Be sure to try your feature out in [IE9](docs/testing-ie9.md), iOS and Android if it's a risk. [BrowserStack live](http://www.browserstack.com) or [Sauce Labs manual](https://saucelabs.com/manual) let you run manual tests in these browsers remotely.
+We support recent versions of Firefox, Chrome, Internet Explorer, Edge, iOS Safari and the Android browsers ([full list of supported browsers and versions](https://support.code.org/hc/en-us/articles/202591743)). Be sure to try your feature out in [IE9](docs/testing-ie9.md), iOS and Android if it's a risk. [Sauce Labs](https://saucelabs.com/manual) or [BrowserStack live](http://www.browserstack.com) let you run manual tests in these browsers remotely.
### Unit tests
@@ -38,7 +38,7 @@ For dashboard changes, be sure to test your changes using `rake test`. For [apps
### UI tests
-Our continuous integration server regularly runs a suite of [UI tests](./dashboard/test/ui) using Selenium / Cucumber which run against many browsers via [BrowserStack Automate](https://www.browserstack.com/automate), and can also be run locally using `chromedriver`. See the [README](./dashboard/test/ui) in that folder for instructions.
+Our continuous integration server regularly runs a suite of [UI tests](./dashboard/test/ui) using Selenium / Cucumber which run against many browsers via [Sauce Labs](https://saucelabs.com/), and can also be run locally using `chromedriver`. See the [README](./dashboard/test/ui) in that folder for instructions.
If your changes might affect level paths, blockly UI, or critical path site logic, be sure to test your changes with a local UI test.
diff --git a/apps/Gruntfile.js b/apps/Gruntfile.js
index b602812739076..3316a6419170e 100644
--- a/apps/Gruntfile.js
+++ b/apps/Gruntfile.js
@@ -488,7 +488,7 @@ module.exports = function (grunt) {
'newer:messages',
'exec:convertScssVars',
'newer:copy:static',
- 'newer:concat',
+ 'concat',
'exec:mochaTest'
]);
diff --git a/apps/i18n/common/ar_sa.json b/apps/i18n/common/ar_sa.json
index 6c623cb6149c3..1531cbdb2ffb1 100644
--- a/apps/i18n/common/ar_sa.json
+++ b/apps/i18n/common/ar_sa.json
@@ -231,5 +231,7 @@
"when": "عندما",
"whenRun": "عند التشغيل",
"workspaceHeaderShort": "مساحة العمل: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/az_az.json b/apps/i18n/common/az_az.json
index 335eb3ca2b6b6..e3a0af0669b28 100644
--- a/apps/i18n/common/az_az.json
+++ b/apps/i18n/common/az_az.json
@@ -231,5 +231,7 @@
"when": "nə zaman",
"whenRun": "icra etdikdə",
"workspaceHeaderShort": "iş sahəsi: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/bg_bg.json b/apps/i18n/common/bg_bg.json
index 3a6247a1ec746..77afb19e276e6 100644
--- a/apps/i18n/common/bg_bg.json
+++ b/apps/i18n/common/bg_bg.json
@@ -231,5 +231,7 @@
"when": "когато",
"whenRun": "при стартиране",
"workspaceHeaderShort": "Работна област: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/bn_bd.json b/apps/i18n/common/bn_bd.json
index adc62c880f03e..f4f1add7fa07d 100644
--- a/apps/i18n/common/bn_bd.json
+++ b/apps/i18n/common/bn_bd.json
@@ -231,5 +231,7 @@
"when": "যখন",
"whenRun": "চালানোর সময়",
"workspaceHeaderShort": "কর্মপরিসর:",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/bs_ba.json b/apps/i18n/common/bs_ba.json
index 8133c86fa4a32..7633a8739a1e4 100755
--- a/apps/i18n/common/bs_ba.json
+++ b/apps/i18n/common/bs_ba.json
@@ -231,5 +231,7 @@
"when": "kada",
"whenRun": "pri pokretanju",
"workspaceHeaderShort": "Radni prostor: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ca_es.json b/apps/i18n/common/ca_es.json
index 592b134e7823b..d09a5c9fd4d5c 100644
--- a/apps/i18n/common/ca_es.json
+++ b/apps/i18n/common/ca_es.json
@@ -231,5 +231,7 @@
"when": "quan",
"whenRun": "quan s'executa",
"workspaceHeaderShort": "Zona de treball: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/cs_cz.json b/apps/i18n/common/cs_cz.json
index 4c8e1ea9e0a91..488b796a8cd07 100644
--- a/apps/i18n/common/cs_cz.json
+++ b/apps/i18n/common/cs_cz.json
@@ -231,5 +231,7 @@
"when": "když",
"whenRun": "po spuštění",
"workspaceHeaderShort": "Pracovní prostor: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/da_dk.json b/apps/i18n/common/da_dk.json
index 01c5ab1916445..a9f033929ca66 100644
--- a/apps/i18n/common/da_dk.json
+++ b/apps/i18n/common/da_dk.json
@@ -231,5 +231,7 @@
"when": "når",
"whenRun": "når programmet kører",
"workspaceHeaderShort": "Arbejdsområde: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/de_de.json b/apps/i18n/common/de_de.json
index 519b59ff46d87..0b91270be05fd 100644
--- a/apps/i18n/common/de_de.json
+++ b/apps/i18n/common/de_de.json
@@ -231,5 +231,7 @@
"when": "wenn",
"whenRun": "beim Ausführen",
"workspaceHeaderShort": "Arbeitsbereich: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/el_gr.json b/apps/i18n/common/el_gr.json
index f38fb0d890d14..c39df1beaad97 100644
--- a/apps/i18n/common/el_gr.json
+++ b/apps/i18n/common/el_gr.json
@@ -231,5 +231,7 @@
"when": "όταν",
"whenRun": "όταν εκτελείται",
"workspaceHeaderShort": "Χώρος εργασίας: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/en_gb.json b/apps/i18n/common/en_gb.json
index 3cb486a599631..b7c7f11a33e0a 100644
--- a/apps/i18n/common/en_gb.json
+++ b/apps/i18n/common/en_gb.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/en_us.json b/apps/i18n/common/en_us.json
index e34d67089233d..badf860a44d7c 100644
--- a/apps/i18n/common/en_us.json
+++ b/apps/i18n/common/en_us.json
@@ -24,6 +24,7 @@
"completedWithoutRecommendedBlock": "Congratulations! You completed Puzzle {puzzleNumber}. (But you could use a different block for stronger code.)",
"continue": "Continue",
"copy": "Copy",
+ "currentVersion": "Current Version",
"debugConsoleHeader": "Debug Console",
"debugCommandsHeaderWhenOpen": "Debug Commands",
"debugCommandsHeaderWhenClosed": "Show Debug Commands",
@@ -184,6 +185,7 @@
"recommendedBlockContextualHintTitle": "Try using a block like this to solve the puzzle.",
"repeat": "repeat",
"resetProgram": "Reset",
+ "restoreThisVersion": "Restore this Version",
"rotateText": "Rotate your device.",
"runProgram": "Run",
"runTooltip": "Run the program defined by the blocks in the workspace.",
diff --git a/apps/i18n/common/es_es.json b/apps/i18n/common/es_es.json
index a8e67f6790314..ed03ead99934c 100644
--- a/apps/i18n/common/es_es.json
+++ b/apps/i18n/common/es_es.json
@@ -231,5 +231,7 @@
"when": "cuando",
"whenRun": "cuando se ejecuta",
"workspaceHeaderShort": "Espacio de trabajo: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/es_mx.json b/apps/i18n/common/es_mx.json
index 4fe02bb8aa3d4..dbbaa4c669abc 100644
--- a/apps/i18n/common/es_mx.json
+++ b/apps/i18n/common/es_mx.json
@@ -231,5 +231,7 @@
"when": "cuando",
"whenRun": "cuando se ejecuta",
"workspaceHeaderShort": "Espacio de trabajo: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/et_ee.json b/apps/i18n/common/et_ee.json
index cdef103f5f344..1ece35b9dd8d3 100644
--- a/apps/i18n/common/et_ee.json
+++ b/apps/i18n/common/et_ee.json
@@ -231,5 +231,7 @@
"when": "kui",
"whenRun": "pärast käivitamist",
"workspaceHeaderShort": "Tööruum: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/eu_es.json b/apps/i18n/common/eu_es.json
index 50807fcbeee86..b446d6d273a9c 100644
--- a/apps/i18n/common/eu_es.json
+++ b/apps/i18n/common/eu_es.json
@@ -231,5 +231,7 @@
"when": "-enean",
"whenRun": "martxan dagoenean",
"workspaceHeaderShort": "Lan eremua: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/fa_af.json b/apps/i18n/common/fa_af.json
index 2ccb6020b0158..7d975517c57a3 100644
--- a/apps/i18n/common/fa_af.json
+++ b/apps/i18n/common/fa_af.json
@@ -231,5 +231,7 @@
"when": "وقتی",
"whenRun": "زمان اجرا",
"workspaceHeaderShort": "محیط کار: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/fa_ir.json b/apps/i18n/common/fa_ir.json
index f320bcd62091d..e10eace8c140c 100644
--- a/apps/i18n/common/fa_ir.json
+++ b/apps/i18n/common/fa_ir.json
@@ -231,5 +231,7 @@
"when": "وقتی",
"whenRun": "زمان اجرا",
"workspaceHeaderShort": "محیط کار: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/fi_fi.json b/apps/i18n/common/fi_fi.json
index 8e63c3a67ec88..da744bfaec28b 100644
--- a/apps/i18n/common/fi_fi.json
+++ b/apps/i18n/common/fi_fi.json
@@ -231,5 +231,7 @@
"when": "kun",
"whenRun": "suoritettaessa",
"workspaceHeaderShort": "Työtila: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/fil_ph.json b/apps/i18n/common/fil_ph.json
index e51798934ee2d..31bd6d82eaf22 100644
--- a/apps/i18n/common/fil_ph.json
+++ b/apps/i18n/common/fil_ph.json
@@ -231,5 +231,7 @@
"when": "kelan",
"whenRun": "kapag tumakbo",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/fr_fr.json b/apps/i18n/common/fr_fr.json
index 5449b77511a71..bc3f53cf2edcb 100644
--- a/apps/i18n/common/fr_fr.json
+++ b/apps/i18n/common/fr_fr.json
@@ -231,5 +231,7 @@
"when": "quand",
"whenRun": "quand l'exécution commence",
"workspaceHeaderShort": "Espace de travail :",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ga_ie.json b/apps/i18n/common/ga_ie.json
index 82212f3fba4c7..0a8b2e1899c71 100644
--- a/apps/i18n/common/ga_ie.json
+++ b/apps/i18n/common/ga_ie.json
@@ -231,5 +231,7 @@
"when": "nuair",
"whenRun": "nuair a ritear é",
"workspaceHeaderShort": "Spás oibre: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/gl_es.json b/apps/i18n/common/gl_es.json
index 89dbeb047c97a..06b9ba359d1a8 100644
--- a/apps/i18n/common/gl_es.json
+++ b/apps/i18n/common/gl_es.json
@@ -231,5 +231,7 @@
"when": "cando",
"whenRun": "cando se executa",
"workspaceHeaderShort": "Espazo de traballo: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/he_il.json b/apps/i18n/common/he_il.json
index 206c94dd3f7b4..5b9c11f5f1069 100644
--- a/apps/i18n/common/he_il.json
+++ b/apps/i18n/common/he_il.json
@@ -231,5 +231,7 @@
"when": "מתי",
"whenRun": "התחל ריצה",
"workspaceHeaderShort": "סביבת העבודה: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/hi_in.json b/apps/i18n/common/hi_in.json
index 2f4fc5b9454b9..aba89ff70e711 100644
--- a/apps/i18n/common/hi_in.json
+++ b/apps/i18n/common/hi_in.json
@@ -231,5 +231,7 @@
"when": "कब",
"whenRun": "जब चलाएँ",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/hr_hr.json b/apps/i18n/common/hr_hr.json
index 54dbc6515db11..b4745f33982fd 100644
--- a/apps/i18n/common/hr_hr.json
+++ b/apps/i18n/common/hr_hr.json
@@ -231,5 +231,7 @@
"when": "kada",
"whenRun": "pri pokretanju",
"workspaceHeaderShort": "Radna površina: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/hu_hu.json b/apps/i18n/common/hu_hu.json
index 19f79ac41b2a2..b6a3e98e9dbf9 100644
--- a/apps/i18n/common/hu_hu.json
+++ b/apps/i18n/common/hu_hu.json
@@ -231,5 +231,7 @@
"when": "amikor",
"whenRun": "futtatáskor",
"workspaceHeaderShort": "Munkaterület: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/hy_am.json b/apps/i18n/common/hy_am.json
index ffdc692ebd52e..6428b5883bccf 100755
--- a/apps/i18n/common/hy_am.json
+++ b/apps/i18n/common/hy_am.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/id_id.json b/apps/i18n/common/id_id.json
index 35a4bff8edf75..199e7cc82116e 100644
--- a/apps/i18n/common/id_id.json
+++ b/apps/i18n/common/id_id.json
@@ -231,5 +231,7 @@
"when": "ketika",
"whenRun": "ketika dijalankan",
"workspaceHeaderShort": "Area kerja: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/is_is.json b/apps/i18n/common/is_is.json
index 11dc9a1c33420..29cc612dcaaef 100644
--- a/apps/i18n/common/is_is.json
+++ b/apps/i18n/common/is_is.json
@@ -231,5 +231,7 @@
"when": "þegar",
"whenRun": "þegar keyrt",
"workspaceHeaderShort": "Vinnusvæði: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/it_it.json b/apps/i18n/common/it_it.json
index 711b86c032075..38ae555735b57 100644
--- a/apps/i18n/common/it_it.json
+++ b/apps/i18n/common/it_it.json
@@ -231,5 +231,7 @@
"when": "quando",
"whenRun": "quando si clicca su \"Esegui\"",
"workspaceHeaderShort": "Area di lavoro: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ja_jp.json b/apps/i18n/common/ja_jp.json
index 8ad49e6a28e90..59cc55e90dc27 100644
--- a/apps/i18n/common/ja_jp.json
+++ b/apps/i18n/common/ja_jp.json
@@ -231,5 +231,7 @@
"when": "とき",
"whenRun": "実行した時",
"workspaceHeaderShort": "ワークスペース:",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ka_ge.json b/apps/i18n/common/ka_ge.json
index 5ef17429f4c68..656ade7cddcbd 100644
--- a/apps/i18n/common/ka_ge.json
+++ b/apps/i18n/common/ka_ge.json
@@ -231,5 +231,7 @@
"when": "როდის",
"whenRun": "გაშვებისას",
"workspaceHeaderShort": "სამუშაო სივრცე: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/kk_kz.json b/apps/i18n/common/kk_kz.json
index 0ebb34ae16cd6..362b837a520cf 100644
--- a/apps/i18n/common/kk_kz.json
+++ b/apps/i18n/common/kk_kz.json
@@ -231,5 +231,7 @@
"when": "кезде",
"whenRun": "қосу кезінде",
"workspaceHeaderShort": "Жұмыс аумағы: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/km_kh.json b/apps/i18n/common/km_kh.json
index 43f4d158d72ad..e423ccb258815 100644
--- a/apps/i18n/common/km_kh.json
+++ b/apps/i18n/common/km_kh.json
@@ -231,5 +231,7 @@
"when": "នៅពេល",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ko_kr.json b/apps/i18n/common/ko_kr.json
index bba4435a44212..0d6500015308f 100644
--- a/apps/i18n/common/ko_kr.json
+++ b/apps/i18n/common/ko_kr.json
@@ -231,5 +231,7 @@
"when": "~할 때",
"whenRun": "실행하면",
"workspaceHeaderShort": "작업 영역: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ku_iq.json b/apps/i18n/common/ku_iq.json
index 8ed237d87e3c0..7afa7f1ce8106 100644
--- a/apps/i18n/common/ku_iq.json
+++ b/apps/i18n/common/ku_iq.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/lt_lt.json b/apps/i18n/common/lt_lt.json
index 502ab719591f3..67c12954a56a5 100644
--- a/apps/i18n/common/lt_lt.json
+++ b/apps/i18n/common/lt_lt.json
@@ -231,5 +231,7 @@
"when": "kada",
"whenRun": "paleidus",
"workspaceHeaderShort": "Darbo laukas: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/lv_lv.json b/apps/i18n/common/lv_lv.json
index 4ac029b87fbbf..02215ff979f8d 100644
--- a/apps/i18n/common/lv_lv.json
+++ b/apps/i18n/common/lv_lv.json
@@ -231,5 +231,7 @@
"when": "kad",
"whenRun": "kad izpilda",
"workspaceHeaderShort": "Darba virsma: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/mi_nz.json b/apps/i18n/common/mi_nz.json
index 20173a26e9269..e5c0fe91f206a 100644
--- a/apps/i18n/common/mi_nz.json
+++ b/apps/i18n/common/mi_nz.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/mk_mk.json b/apps/i18n/common/mk_mk.json
index 8d7f174489e01..05e8774f63719 100644
--- a/apps/i18n/common/mk_mk.json
+++ b/apps/i18n/common/mk_mk.json
@@ -231,5 +231,7 @@
"when": "Кога",
"whenRun": "Кога трча",
"workspaceHeaderShort": "Работна површина: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/mr_in.json b/apps/i18n/common/mr_in.json
index 3cb486a599631..b7c7f11a33e0a 100644
--- a/apps/i18n/common/mr_in.json
+++ b/apps/i18n/common/mr_in.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ms_my.json b/apps/i18n/common/ms_my.json
index cc2acf291db0a..b64d02d1cf902 100644
--- a/apps/i18n/common/ms_my.json
+++ b/apps/i18n/common/ms_my.json
@@ -231,5 +231,7 @@
"when": "apabila",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/mt_mt.json b/apps/i18n/common/mt_mt.json
index e91cc7fd88a85..fb4f081745c05 100755
--- a/apps/i18n/common/mt_mt.json
+++ b/apps/i18n/common/mt_mt.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ne_np.json b/apps/i18n/common/ne_np.json
index 687941ad8c4fd..e036be730f968 100644
--- a/apps/i18n/common/ne_np.json
+++ b/apps/i18n/common/ne_np.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/nl_nl.json b/apps/i18n/common/nl_nl.json
index 03105b0acd866..d243005ec754f 100644
--- a/apps/i18n/common/nl_nl.json
+++ b/apps/i18n/common/nl_nl.json
@@ -231,5 +231,7 @@
"when": "wanneer",
"whenRun": "als gestart",
"workspaceHeaderShort": "Werkplaats: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/nn_no.json b/apps/i18n/common/nn_no.json
index 7740276daa5ae..296fb91558881 100755
--- a/apps/i18n/common/nn_no.json
+++ b/apps/i18n/common/nn_no.json
@@ -231,5 +231,7 @@
"when": "når",
"whenRun": "når den kjører",
"workspaceHeaderShort": "Arbeidsområde: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/no_no.json b/apps/i18n/common/no_no.json
index 84ce35c377a59..f73162f2bf284 100644
--- a/apps/i18n/common/no_no.json
+++ b/apps/i18n/common/no_no.json
@@ -231,5 +231,7 @@
"when": "når",
"whenRun": "når den køyrer",
"workspaceHeaderShort": "Arbeidsområde: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/pl_pl.json b/apps/i18n/common/pl_pl.json
index 27d2799e5c2f3..9375145df567b 100644
--- a/apps/i18n/common/pl_pl.json
+++ b/apps/i18n/common/pl_pl.json
@@ -231,5 +231,7 @@
"when": "kiedy",
"whenRun": "po uruchomieniu",
"workspaceHeaderShort": "Obszar roboczy: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ps_af.json b/apps/i18n/common/ps_af.json
index 9d57641d92d3e..78e12c6b217c2 100755
--- a/apps/i18n/common/ps_af.json
+++ b/apps/i18n/common/ps_af.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/pt_br.json b/apps/i18n/common/pt_br.json
index 0a428b830010d..7e508dde28af0 100644
--- a/apps/i18n/common/pt_br.json
+++ b/apps/i18n/common/pt_br.json
@@ -231,5 +231,7 @@
"when": "quando",
"whenRun": "quando executar",
"workspaceHeaderShort": "Área de trabalho: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/pt_pt.json b/apps/i18n/common/pt_pt.json
index 354ac00a736b7..383078b005978 100644
--- a/apps/i18n/common/pt_pt.json
+++ b/apps/i18n/common/pt_pt.json
@@ -231,5 +231,7 @@
"when": "quando",
"whenRun": "quando executar",
"workspaceHeaderShort": "Espaço de trabalho: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ro_ro.json b/apps/i18n/common/ro_ro.json
index 4e9f16b7bafbc..71bd8cd62aa5c 100644
--- a/apps/i18n/common/ro_ro.json
+++ b/apps/i18n/common/ro_ro.json
@@ -231,5 +231,7 @@
"when": "când",
"whenRun": "când rulezi",
"workspaceHeaderShort": "Spaţiu de lucru: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ru_ru.json b/apps/i18n/common/ru_ru.json
index 4800c70183e6a..1d40347335764 100644
--- a/apps/i18n/common/ru_ru.json
+++ b/apps/i18n/common/ru_ru.json
@@ -231,5 +231,7 @@
"when": "когда",
"whenRun": "При запуске",
"workspaceHeaderShort": "Место сбора блоков: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/se_fi.json b/apps/i18n/common/se_fi.json
index 84effd24308cd..8c7135a917f24 100644
--- a/apps/i18n/common/se_fi.json
+++ b/apps/i18n/common/se_fi.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/si_lk.json b/apps/i18n/common/si_lk.json
index dae8df24c0552..3f62b96d973a5 100644
--- a/apps/i18n/common/si_lk.json
+++ b/apps/i18n/common/si_lk.json
@@ -231,5 +231,7 @@
"when": "විට",
"whenRun": "දුවන විට",
"workspaceHeaderShort": "වැඩ අවකාශය: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/sk_sk.json b/apps/i18n/common/sk_sk.json
index 6c7ecadf5ce53..bdec28a583940 100644
--- a/apps/i18n/common/sk_sk.json
+++ b/apps/i18n/common/sk_sk.json
@@ -231,5 +231,7 @@
"when": "keď",
"whenRun": "pri spustení",
"workspaceHeaderShort": "Pracovná plocha: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/sl_si.json b/apps/i18n/common/sl_si.json
index 95dd84ffba4c8..10e0f7ddca8da 100644
--- a/apps/i18n/common/sl_si.json
+++ b/apps/i18n/common/sl_si.json
@@ -231,5 +231,7 @@
"when": "ko",
"whenRun": "ob zagonu",
"workspaceHeaderShort": "Delovni prostor: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/sq_al.json b/apps/i18n/common/sq_al.json
index 5ec255e877dbb..3e958e6b836e5 100644
--- a/apps/i18n/common/sq_al.json
+++ b/apps/i18n/common/sq_al.json
@@ -231,5 +231,7 @@
"when": "kur",
"whenRun": "kur vrapon",
"workspaceHeaderShort": "Vendi i punës: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/sr_sp.json b/apps/i18n/common/sr_sp.json
index 6a3fa2f63c062..dc20ca04c6b59 100644
--- a/apps/i18n/common/sr_sp.json
+++ b/apps/i18n/common/sr_sp.json
@@ -231,5 +231,7 @@
"when": "када",
"whenRun": "Када кренеш",
"workspaceHeaderShort": "Радни простор: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/sv_se.json b/apps/i18n/common/sv_se.json
index 7ba92bc707708..a52db4279fd44 100644
--- a/apps/i18n/common/sv_se.json
+++ b/apps/i18n/common/sv_se.json
@@ -231,5 +231,7 @@
"when": "när",
"whenRun": "vid start",
"workspaceHeaderShort": "Arbetsyta: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ta_in.json b/apps/i18n/common/ta_in.json
index 8562ad7b07d19..c72130e215af0 100644
--- a/apps/i18n/common/ta_in.json
+++ b/apps/i18n/common/ta_in.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/th_th.json b/apps/i18n/common/th_th.json
index 889d2a9961d1f..1c3ea60184442 100644
--- a/apps/i18n/common/th_th.json
+++ b/apps/i18n/common/th_th.json
@@ -231,5 +231,7 @@
"when": "เมื่อ",
"whenRun": "เมื่อเรียกให้ทำงาน",
"workspaceHeaderShort": "พื้นที่ทำงาน: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/tr_tr.json b/apps/i18n/common/tr_tr.json
index 6a074b250360e..053f91df3ef1b 100644
--- a/apps/i18n/common/tr_tr.json
+++ b/apps/i18n/common/tr_tr.json
@@ -231,5 +231,7 @@
"when": "Ne zaman",
"whenRun": "Çalıştığı zaman",
"workspaceHeaderShort": "Çalışma alanı: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/uk_ua.json b/apps/i18n/common/uk_ua.json
index 8642f995e1083..9a055567967a2 100644
--- a/apps/i18n/common/uk_ua.json
+++ b/apps/i18n/common/uk_ua.json
@@ -231,5 +231,7 @@
"when": "коли",
"whenRun": "коли гра починається",
"workspaceHeaderShort": "Робоча область: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/ur_pk.json b/apps/i18n/common/ur_pk.json
index b70fe28314a75..203c32da08247 100644
--- a/apps/i18n/common/ur_pk.json
+++ b/apps/i18n/common/ur_pk.json
@@ -231,5 +231,7 @@
"when": "کب",
"whenRun": "جب رن ہو تو",
"workspaceHeaderShort": "ورک اسپیس ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/uz_uz.json b/apps/i18n/common/uz_uz.json
index 2ef2c201697d6..10227b8e95be3 100644
--- a/apps/i18n/common/uz_uz.json
+++ b/apps/i18n/common/uz_uz.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/vi_vn.json b/apps/i18n/common/vi_vn.json
index 8de621e5210f4..1103021a5125b 100644
--- a/apps/i18n/common/vi_vn.json
+++ b/apps/i18n/common/vi_vn.json
@@ -231,5 +231,7 @@
"when": "Khi nào",
"whenRun": "Khi chạy",
"workspaceHeaderShort": "Không gian làm việc:",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/zh_cn.json b/apps/i18n/common/zh_cn.json
index 8c9c6572dc231..147e064ef633d 100644
--- a/apps/i18n/common/zh_cn.json
+++ b/apps/i18n/common/zh_cn.json
@@ -231,5 +231,7 @@
"when": "当",
"whenRun": "当运行时",
"workspaceHeaderShort": "工作区域",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/zh_tw.json b/apps/i18n/common/zh_tw.json
index d9270e4cd9c62..b7baa76509a6a 100644
--- a/apps/i18n/common/zh_tw.json
+++ b/apps/i18n/common/zh_tw.json
@@ -231,5 +231,7 @@
"when": "當",
"whenRun": "當按下\"執行\"時",
"workspaceHeaderShort": "工作區:",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/i18n/common/zu_za.json b/apps/i18n/common/zu_za.json
index 90c0e38efc2c9..f01c69a944470 100644
--- a/apps/i18n/common/zu_za.json
+++ b/apps/i18n/common/zu_za.json
@@ -231,5 +231,7 @@
"when": "when",
"whenRun": "when run",
"workspaceHeaderShort": "Workspace: ",
- "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more."
+ "currentVersion": "Current Version",
+ "errorGenericLintError": "Your program contains an editor warning that needs to be corrected. Hover over the icons near the line numbers in the editor to learn more.",
+ "restoreThisVersion": "Restore this Version"
}
\ No newline at end of file
diff --git a/apps/src/applab/AppLabView.jsx b/apps/src/applab/AppLabView.jsx
index 2d328776f7624..a42b9743039e9 100644
--- a/apps/src/applab/AppLabView.jsx
+++ b/apps/src/applab/AppLabView.jsx
@@ -119,7 +119,7 @@ var AppLabView = React.createClass({
},
componentDidMount: function () {
- if (this.props.instructionsInTopPane) {
+ if (this.props.showInstructions) {
this.adjustTopPaneHeight();
window.addEventListener('resize', this.onResize);
@@ -129,7 +129,7 @@ var AppLabView = React.createClass({
},
componentWillUnmount: function () {
- if (this.props.instructionsInTopPane) {
+ if (this.props.showInstructions) {
window.removeEventListener("resize", this.onResize);
}
},
@@ -148,7 +148,7 @@ var AppLabView = React.createClass({
}
// Or we may not display the instructions pane at all
- if (!this.props.instructionsInTopPane) {
+ if (!this.props.showInstructions) {
height = 0;
}
@@ -179,7 +179,7 @@ var AppLabView = React.createClass({
Saved
{this.getLastModifiedTimestamp()} -#{flakiness_output}" - end -end - -UI_TEST_SYMLINK = dashboard_dir 'public/ui_test' -file UI_TEST_SYMLINK do - Dir.chdir(dashboard_dir('public')) do - RakeUtils.system_ 'ln', '-s', '../test/ui', 'ui_test' - end -end - -task :regular_ui_tests => [UI_TEST_SYMLINK] do - Dir.chdir(dashboard_dir('test/ui')) do - HipChat.log 'Running dashboard UI tests...' - failed_browser_count = RakeUtils.system_with_hipchat_logging 'bundle', 'exec', './runner.rb', '-d', 'test-studio.code.org', '--parallel', '70', '--magic_retry', '--html', '--fail_fast' - if failed_browser_count == 0 - message = '┬──┬ ノ( ゜-゜ノ) UI tests for dashboard succeeded.' - HipChat.log message - HipChat.developers message, color: 'green' - else - message = "(╯°□°)╯︵ ┻━┻ UI tests for dashboard failed on #{failed_browser_count} browser(s)." - HipChat.log message, color: 'red' - HipChat.developers message, color: 'red', notify: 1 - end - end -end - -task :eyes_ui_tests => [UI_TEST_SYMLINK] do - Dir.chdir(dashboard_dir('test/ui')) do - HipChat.log 'Running dashboard UI visual tests...' - eyes_features = `grep -lr '@eyes' features`.split("\n") - failed_browser_count = RakeUtils.system_with_hipchat_logging 'bundle', 'exec', './runner.rb', '-c', 'ChromeLatestWin7,iPhone', '-d', 'test-studio.code.org', '--eyes', '--html', '-f', eyes_features.join(","), '--parallel', (eyes_features.count * 2).to_s - if failed_browser_count == 0 - message = '⊙‿⊙ Eyes tests for dashboard succeeded, no changes detected.' - HipChat.log message - HipChat.developers message, color: 'green' - else - message = 'ಠ_ಠ Eyes tests for dashboard failed. See the console for results or to modify baselines.' - HipChat.log message, color: 'red' - HipChat.developers message, color: 'red', notify: 1 - end - end -end - -# do the eyes and browserstack ui tests in parallel -multitask ui_tests: [:eyes_ui_tests, :regular_ui_tests] - -$websites_test = build_task('websites-test', [deploy_dir('rebuild'), BLOCKLY_CORE_TASK, :apps_task, :code_studio_task, :build_with_cloudfront, :deploy, :pegasus_unit_tests, :shared_unit_tests, :dashboard_unit_tests, :ui_test_flakiness, :ui_tests]) - -task 'test-websites' => [$websites_test] diff --git a/aws/build.rake b/aws/build.rake new file mode 120000 index 0000000000000..31ff7721e4cc7 --- /dev/null +++ b/aws/build.rake @@ -0,0 +1 @@ +./ci_build.rake \ No newline at end of file diff --git a/aws/build_and_mail_log b/aws/build_and_mail_log deleted file mode 100755 index 23b310f6e8b2e..0000000000000 --- a/aws/build_and_mail_log +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env ruby -# -# BUILD_AND_MAIL_LOG is a terrible name. The MAIL_LOG part was split out into CRONJOB. -# -# This script actually defers to BUILD for the actual building and then delivers a -# higher fidelity set of HipChat notifications than CRONJOB provides, e.g. red-colored -# notification messages when the build fails, gray colored blocks with Git commit -# messages, etc. -# -# FUTURE DIRECTION: This should probably be collapsed into BUILD itself. -# - -require_relative '../deployment' -require 'cdo/rake_utils' -require 'cdo/hip_chat' -require 'cdo/only_one' -require 'mail' - -def format_duration(total_seconds) - total_seconds = total_seconds.to_i - minutes = (total_seconds / 60).to_i - seconds = total_seconds - (minutes * 60) - "%.1d:%.2d minutes" % [minutes, seconds] -end - -def main() - start_time = Time.now.to_i - # Run the build script and exit if it didn't do anything. - script = File.expand_path('../build', __FILE__) - log = `\"#{script}\" #{ARGV.join(' ')} 2>&1`.strip - status = $?.exitstatus - return status if status == 0 && log.empty? - - Dir.chdir(deploy_dir) do - commit_url = "https://github.com/code-dot-org/code-dot-org/commit/#{RakeUtils.git_revision}" - # Notify the HipChat channels about what happened. - projects = ARGV.join(' ') - time_message = " 🕐 #{format_duration(Time.now.to_i - start_time)}" - if status == 0 - message = "#{projects} built." + time_message - - HipChat.log message, color: 'green' - - HipChat.developers message, color: 'green' - HipChat.developers commit_url, color: 'gray', message_format: 'text' - else - message = "#{projects} failed to build!" + time_message - - HipChat.log message, color: 'red' - HipChat.log "/quote #{log}", color: 'gray', message_format: 'text' - - HipChat.developers message, color: 'red', notify: 1 - HipChat.developers commit_url, color: 'gray', message_format: 'text' - end - end - - # Return the same output and status code that BUILD returned. - puts log - status -end - -main() if only_one_running?(__FILE__) diff --git a/aws/build_and_mail_log b/aws/build_and_mail_log new file mode 120000 index 0000000000000..076b3c8c2197f --- /dev/null +++ b/aws/build_and_mail_log @@ -0,0 +1 @@ +./ci_build \ No newline at end of file diff --git a/aws/ci_build b/aws/ci_build new file mode 100755 index 0000000000000..b926c2926b11d --- /dev/null +++ b/aws/ci_build @@ -0,0 +1,124 @@ +#!/usr/bin/env ruby +# +# CI_BUILD is the core command in our polling-based continuous deployment system. It checks for upstream +# commits on the current branch. +# +# If no changes are detected it exits silently. +# +# If changes are detected, CI_BUILD fetches them, gets the commit messages for them (written out as +# the temp file 'rebuild') and displays them in chat as a purple "build started" message. Then +# CI_BUILD invokes CI_BUILD.RAKE to run the build using dependency-based build rules. +# +# NOTE: When the build starts a BUILD-STARTED file is created, and this file is deleted when the +# build script finishes. This file is NOT deleted if the build system itself is broken and the +# presence of this file will cause the system to attempt to pull and rebuild constantly over and +# over until it succeeds. This may happen often, but it is probably a safeguard to keep around because +# in the rare cases where the build scripts are damaged, this ensures the machines can be restored simply +# by checking in a fix (vs. needing to SSH to the machine and fix manually). +# +# NOTE: running `touch build-started` (or running the `bin/start-build` script) +# is an easy way to force a rebuild without needing to make a commit. +# +require_relative '../deployment' +require 'cdo/rake_utils' +require 'cdo/hip_chat' +require 'cdo/only_one' +require 'mail' + +STARTED = 'build-started' + +def format_duration(total_seconds) + total_seconds = total_seconds.to_i + minutes = (total_seconds / 60).to_i + seconds = total_seconds - (minutes * 60) + "%.1d:%.2d minutes" % [minutes, seconds] +end + +def capture_stdout + old_stdout = $stdout + $stdout = StringIO.new('', 'w') + yield + $stdout.string +ensure + $stdout = old_stdout +end + +def build() + Dir.chdir(deploy_dir) do + return 0 unless RakeUtils.git_updates_available? || File.file?(STARTED) || !CDO.daemon + FileUtils.touch STARTED + + RakeUtils.git_fetch + count = RakeUtils.git_update_count + RakeUtils.git_pull if count > 0 + count = [1, count].max + + log = `git log --pretty=format:"%h %s (%an)" -n #{count}` + IO.write(deploy_dir('rebuild'), log) + + HipChat.log "https://github.com/code-dot-org/code-dot-org/commit/#{`git rev-parse HEAD`}", message_format: 'text', color: 'purple' + + # Ensure updated Gemfile.lock dependencies are installed. + RakeUtils.bundle_install + + # Run `sudo chef-client` to ensure that the deploy respect updates to the Chef config + # (e.g. the cdo-servers attribute describing which servers to deploy). + Dir.chdir(aws_dir) do + # Ensure the chef cookbooks are up to date. + RakeUtils.rake '--rakefile', 'ci_build.rake', 'chef_update' + RakeUtils.system 'sudo', 'chef-client' + end + + status = 0 + Dir.chdir(aws_dir) do + status = begin + RakeUtils.rake '--rakefile', 'ci_build.rake', *ARGV + rescue => e + CDO.backtrace e + end + end + + FileUtils.rm STARTED if File.file?(STARTED) + + status + end +end + +def main() + start_time = Time.now.to_i + # Run the build command and exit if it didn't do anything. + status = 0 + log = capture_stdout { status = build } + return status if status == 0 && log.empty? + + Dir.chdir(deploy_dir) do + commit_url = "https://github.com/code-dot-org/code-dot-org/commit/#{RakeUtils.git_revision}" + # Notify the HipChat channels about what happened. + projects = ARGV.join(' ') + projects = 'websites' if projects.empty? + time_message = " 🕐 #{format_duration(Time.now.to_i - start_time)}" + if status == 0 + message = "#{projects} built." + time_message + + HipChat.log message, color: 'green' + + HipChat.developers message, color: 'green' + HipChat.developers commit_url, color: 'gray', message_format: 'text' + else + message = "#{projects} failed to build!" + time_message + + HipChat.log message, color: 'red' + HipChat.log "/quote #{log}", color: 'gray', message_format: 'text' + HipChat.log "/quote #{status}", color: 'gray', message_format: 'text' + + HipChat.developers message, color: 'red', notify: 1 + HipChat.developers commit_url, color: 'gray', message_format: 'text' + end + end + + # Return the same output and status code that BUILD returned. + puts log + status +end + +main() if only_one_running?(__FILE__) diff --git a/aws/ci_build.rake b/aws/ci_build.rake new file mode 100644 index 0000000000000..4c78e7f016d64 --- /dev/null +++ b/aws/ci_build.rake @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# CI_BUILD.RAKE used to contain everything that is now in the top-level Rakefile, i.e. it used to be +# the entire build system and developers needed to remember separate steps to build each project +# or wait for CI. Since then, the building of projects has been moved out to the top-level Rakefile +# (which this now calls) and this Rakefile is responsible for the "integration" portions of continuous +# integration. +# +# This Rakefile CAN be confusing to read because it is the kind of Rakefile that globs the filesystem +# and then calls functions that generate the rules that are eventually invoked. +# + +require_relative '../deployment' +require 'cdo/rake_utils' +require 'cdo/hip_chat' +require 'cdo/only_one' +require 'shellwords' +require 'cdo/aws/cloudfront' +require 'cdo/aws/s3_packaging' + +def format_duration(total_seconds) + total_seconds = total_seconds.to_i + minutes = (total_seconds / 60).to_i + seconds = total_seconds - (minutes * 60) + "%.1d:%.2d minutes" % [minutes, seconds] +end + +def with_hipchat_logging(name) + start_time = Time.now + HipChat.log "Running #{name}..." + yield if block_given? + HipChat.log "#{name} succeeded in #{format_duration(Time.now - start_time)}" + +rescue => e + # notify developers room and our own room + "#{name} failed in #{format_duration(Time.now - start_time)}".tap do |message| + HipChat.log message, color: 'red', notify: 1 + HipChat.developers message, color: 'red', notify: 1 + end + # log detailed error information in our own room + HipChat.log "/quote #{e}\n#{CDO.backtrace e}", message_format: 'text' + raise +end + +# +# build_task - BUILDS a TASK that uses a hidden (.dotfile) to keep build steps idempotent. The file +# ".
#{flakiness_output}" + end +end + +UI_TEST_SYMLINK = dashboard_dir 'public/ui_test' +file UI_TEST_SYMLINK do + Dir.chdir(dashboard_dir('public')) do + RakeUtils.system_ 'ln', '-s', '../test/ui', 'ui_test' + end +end + +task :regular_ui_tests => [UI_TEST_SYMLINK] do + Dir.chdir(dashboard_dir('test/ui')) do + HipChat.log 'Running dashboard UI tests...' + failed_browser_count = RakeUtils.system_with_hipchat_logging 'bundle', 'exec', './runner.rb', '-d', 'test-studio.code.org', '--parallel', '70', '--magic_retry', '--html', '--fail_fast' + if failed_browser_count == 0 + message = '┬──┬ ノ( ゜-゜ノ) UI tests for dashboard succeeded.' + HipChat.log message + HipChat.developers message, color: 'green' + else + message = "(╯°□°)╯︵ ┻━┻ UI tests for dashboard failed on #{failed_browser_count} browser(s)." + HipChat.log message, color: 'red' + HipChat.developers message, color: 'red', notify: 1 + end + end +end + +task :eyes_ui_tests => [UI_TEST_SYMLINK] do + Dir.chdir(dashboard_dir('test/ui')) do + HipChat.log 'Running dashboard UI visual tests...' + eyes_features = `grep -lr '@eyes' features`.split("\n") + failed_browser_count = RakeUtils.system_with_hipchat_logging 'bundle', 'exec', './runner.rb', '-c', 'ChromeLatestWin7,iPhone', '-d', 'test-studio.code.org', '--eyes', '--html', '-f', eyes_features.join(","), '--parallel', (eyes_features.count * 2).to_s + if failed_browser_count == 0 + message = '⊙‿⊙ Eyes tests for dashboard succeeded, no changes detected.' + HipChat.log message + HipChat.developers message, color: 'green' + else + message = 'ಠ_ಠ Eyes tests for dashboard failed. See the console for results or to modify baselines.' + HipChat.log message, color: 'red' + HipChat.developers message, color: 'red', notify: 1 + end + end +end + +# do the eyes and sauce labs ui tests in parallel +multitask ui_tests: [:eyes_ui_tests, :regular_ui_tests] + +$websites_test = build_task('websites-test', [ + 'websites', + :pegasus_unit_tests, + :shared_unit_tests, + :dashboard_unit_tests, + :ui_test_flakiness, + :ui_tests +]) + +task 'test-websites' => [$websites_test] +task 'default' => rack_env?(:test) ? 'test-websites' : 'websites' diff --git a/bin/cronjob b/bin/cronjob index a19c1a602c606..acdb86d0c742b 100755 --- a/bin/cronjob +++ b/bin/cronjob @@ -7,16 +7,13 @@ # SUCCESS (no notifications): The process exited with a 0 exit code with no output (after # stripping whitespace). # -# WARNING (email notification, HipChat yellow message): The process exited with a non-0 exit code +# WARNING (email notification): The process exited with a non-0 exit code # or returned output. # # ERROR (not currently differentiated): A non-0 exit code could be elevated to mean error and # result in a red HipChat message and/or channel notification. # -# FUTURE THOUGHTS: It may make sense to deliver WARNING and ERROR cases to HoneyBadger.io in -# addition to (or instead of) HipChat. -# -# CRONJOBs are defined the crontab: `chef/cookbooks/cdo-apps/templates/default/crontab.erb`. +# CRONJOBs are defined the cdo-apps::crontab Chef recipe: `chef/cookbooks/cdo-apps/recipes/crontab.rb`. # require_relative '../deployment.rb' diff --git a/bin/start-build b/bin/start-build index a642dd9ca163c..c0c9ec76ffb2d 100755 --- a/bin/start-build +++ b/bin/start-build @@ -2,8 +2,8 @@ require_relative '../deployment.rb' require 'cdo/hip_chat' -# restarts the build on chef-managed servers by touching build-started, -# which a cron job looks for every minute as a signal to restart the build. +# restarts the build on daemon servers by touching build-started, +# where a cron job looks for every minute as a signal to restart the build. raise "#{$0} does not work in development mode" if rack_env?(:development) diff --git a/code-studio/src/js/clientState.js b/code-studio/src/js/clientState.js index bf5ba0af3f431..173d34bf25369 100644 --- a/code-studio/src/js/clientState.js +++ b/code-studio/src/js/clientState.js @@ -9,6 +9,8 @@ var sessionStorage = window.sessionStorage; var clientState = module.exports = {}; +clientState.queryParams = require('./utils').queryParams; + /** * Number of days before client state cookie expires. * @type {number} @@ -32,27 +34,6 @@ clientState.reset = function () { } catch (e) {} }; -/** - * Gets the URL querystring params. - * @param name {string=} Optionally pull a specific param. - * @return {object|string} Hash of params, or param string if `name` is specified. - */ -clientState.queryParams = function (name) { - var pairs = location.search.substr(1).split('&'); - var params = {}; - pairs.forEach(function (pair) { - var split = pair.split('='); - if (split.length === 2) { - params[split[0]] = split[1]; - } - }); - - if (name) { - return params[name]; - } - return params; -}; - /** * Returns the client-cached copy of the level source for the given script * level, if it's newer than the given timestamp. diff --git a/code-studio/src/js/initApp/initApp.js b/code-studio/src/js/initApp/initApp.js index 19a010ab8c7e9..1225e355e8bac 100644 --- a/code-studio/src/js/initApp/initApp.js +++ b/code-studio/src/js/initApp/initApp.js @@ -45,7 +45,7 @@ window.apps = { if (appOptions.level.projectTemplateLevelName || appOptions.app === 'applab' || appOptions.app === 'gamelab') { $('#clear-puzzle-header').hide(); // Only show Version History button if the user owns this project - if (project.isOwner()) { + if (project.isEditable()) { $('#versions-header').show(); } } diff --git a/code-studio/src/js/initApp/project.js b/code-studio/src/js/initApp/project.js index 423d0a29c3d92..48710c3afc860 100644 --- a/code-studio/src/js/initApp/project.js +++ b/code-studio/src/js/initApp/project.js @@ -15,6 +15,7 @@ var channels = require('./clientApi').create('/v3/channels'); var showProjectAdmin = require('../showProjectAdmin'); var header = require('../header'); +var queryParams = require('../utils').queryParams; // Name of the packed source file var SOURCE_FILE = 'main.json'; @@ -145,6 +146,11 @@ var projects = module.exports = { }); }, + /** + * Is the current project (if any) editable by the logged in user (if any)? + */ + isEditable: isEditable, + /** * @returns {boolean} true if we're frozen */ @@ -594,7 +600,7 @@ var projects = module.exports = { fetchAbuseScore(function () { deferred.resolve(); }); - }); + }, queryParams('version')); } }); } else { @@ -612,7 +618,7 @@ var projects = module.exports = { fetchAbuseScore(function () { deferred.resolve(); }); - }); + }, queryParams('version')); } }); } else { @@ -641,8 +647,9 @@ var projects = module.exports = { * sources api * @param {object} channelData Data we fetched from channels api * @param {function} callback + * @param {string?} version Optional version to load */ -function fetchSource(channelData, callback) { +function fetchSource(channelData, callback, version) { // Explicitly remove levelSource/levelHtml from channels delete channelData.levelSource; delete channelData.levelHtml; @@ -654,12 +661,16 @@ function fetchSource(channelData, callback) { projects.setTitle(current.name); if (channelData.migratedToS3) { - sources.fetch(current.id + '/' + SOURCE_FILE, function (err, data) { + var url = current.id + '/' + SOURCE_FILE; + if (version) { + url += '?version=' + version; + } + sources.fetch(url, function (err, data) { if (err) { console.warn('unable to fetch project source file', err); data = { source: '', - html: '', + html: '' }; } unpackSources(data); @@ -698,7 +709,7 @@ function executeCallback(callback, data) { * is the current project (if any) editable by the logged in user (if any)? */ function isEditable() { - return (current && current.isOwner && !current.frozen); + return current && current.isOwner && !current.frozen && !queryParams('version'); } /** @@ -747,7 +758,6 @@ function redirectFromHashUrl() { return false; } - var pathInfo = parsePath(); location.href = newUrl; return true; } @@ -765,18 +775,20 @@ function parsePath() { pathname += location.hash.replace('#', '/'); } - if (pathname.split('/')[PathPart.PROJECTS] !== 'p' && - pathname.split('/')[PathPart.PROJECTS] !== 'projects') { + var tokens = pathname.split('/'); + + if (tokens[PathPart.PROJECTS] !== 'p' && + tokens[PathPart.PROJECTS] !== 'projects') { return { appName: null, channelId: null, - action: null, + action: null }; } return { - appName: pathname.split('/')[PathPart.APP], - channelId: pathname.split('/')[PathPart.CHANNEL_ID], - action: pathname.split('/')[PathPart.ACTION] + appName: tokens[PathPart.APP], + channelId: tokens[PathPart.CHANNEL_ID], + action: tokens[PathPart.ACTION] }; } diff --git a/code-studio/src/js/utils.js b/code-studio/src/js/utils.js new file mode 100644 index 0000000000000..5e10917ecfe11 --- /dev/null +++ b/code-studio/src/js/utils.js @@ -0,0 +1,24 @@ +'use strict'; + +module.exports = { + /** + * Gets the URL querystring params. + * @param name {string=} Optionally pull a specific param. + * @return {object|string} Hash of params, or param string if `name` is specified. + */ + queryParams: function (name) { + var pairs = location.search.substr(1).split('&'); + var params = {}; + pairs.forEach(function (pair) { + var split = pair.split('='); + if (split.length === 2) { + params[split[0]] = split[1]; + } + }); + + if (name) { + return params[name]; + } + return params; + } +}; diff --git a/cookbooks/Berksfile.lock b/cookbooks/Berksfile.lock index b9070790dcb9d..8941132efd14b 100644 --- a/cookbooks/Berksfile.lock +++ b/cookbooks/Berksfile.lock @@ -51,7 +51,7 @@ GRAPH seven_zip (>= 0.0.0) windows (>= 0.0.0) build-essential (2.1.3) - cdo-apps (0.2.17) + cdo-apps (0.2.19) apt (>= 0.0.0) build-essential (>= 0.0.0) cdo-java-7 (>= 0.0.0) diff --git a/cookbooks/cdo-apps/.kitchen.yml b/cookbooks/cdo-apps/.kitchen.yml index 0ae9bd6179a01..d708d0505ca13 100644 --- a/cookbooks/cdo-apps/.kitchen.yml +++ b/cookbooks/cdo-apps/.kitchen.yml @@ -22,7 +22,7 @@ platforms: - recipe[cdo-apps] suites: - name: default - - name: nginx + - name: daemon attributes: cdo-apps: - nginx_enabled: true + daemon: true diff --git a/cookbooks/cdo-apps/Berksfile.lock b/cookbooks/cdo-apps/Berksfile.lock index 76541f58ce985..bdd7b85a16bec 100644 --- a/cookbooks/cdo-apps/Berksfile.lock +++ b/cookbooks/cdo-apps/Berksfile.lock @@ -4,10 +4,14 @@ DEPENDENCIES metadata: true cdo-github-access path: ../cdo-github-access + cdo-java-7 + path: ../cdo-java-7 cdo-mysql path: ../cdo-mysql cdo-nginx path: ../cdo-nginx + cdo-nodejs + path: ../cdo-nodejs cdo-postfix path: ../cdo-postfix cdo-repository @@ -29,15 +33,19 @@ GRAPH 7-zip (1.0.2) windows (>= 1.2.2) apt (2.9.2) - brightbox-ruby (1.2.1) - apt (>= 0.0.0) + ark (1.0.1) + build-essential (>= 0.0.0) + seven_zip (>= 0.0.0) + windows (>= 0.0.0) build-essential (2.3.1) 7-zip (>= 0.0.0) - cdo-apps (0.2.6) + cdo-apps (0.2.19) apt (>= 0.0.0) build-essential (>= 0.0.0) + cdo-java-7 (>= 0.0.0) cdo-mysql (>= 0.0.0) cdo-nginx (>= 0.0.0) + cdo-nodejs (>= 0.0.0) cdo-postfix (>= 0.0.0) cdo-repository (>= 0.0.0) cdo-ruby (>= 0.0.0) @@ -46,27 +54,42 @@ GRAPH omnibus_updater (>= 0.0.0) sudo-user (>= 0.0.0) cdo-github-access (0.1.1) + cdo-java-7 (0.1.0) + build-essential (>= 0.0.0) cdo-mysql (0.1.1) - cdo-nginx (0.0.2) + cdo-nginx (0.0.8) apt (>= 0.0.0) ssl_certificate (>= 0.0.0) + cdo-nodejs (0.2.1) + nodejs (>= 0.0.0) cdo-postfix (0.2.0) apt (>= 0.0.0) postfix (>= 0.0.0) cdo-repository (0.2.1) cdo-github-access (>= 0.0.0) - cdo-ruby (0.1.1) - brightbox-ruby (>= 0.0.0) - build-essential (>= 0.0.0) - cdo-secrets (0.1.0) - cdo-varnish (0.3.6) + cdo-ruby (0.2.0) + cdo-secrets (0.1.1) + cdo-varnish (0.3.10) apt (>= 0.0.0) chef_handler (1.3.0) + homebrew (2.1.0) + build-essential (>= 2.1.2) + nodejs (2.4.4) + apt (>= 0.0.0) + ark (>= 0.0.0) + build-essential (>= 0.0.0) + homebrew (>= 0.0.0) + yum-epel (>= 0.0.0) ohai (2.1.0) omnibus_updater (2.0.0) postfix (3.7.0) + seven_zip (2.0.0) + windows (>= 1.2.2) ssl_certificate (1.11.0) sudo-user (0.1.0) ohai (>= 0.0.0) windows (1.39.1) chef_handler (>= 0.0.0) + yum (3.10.0) + yum-epel (0.6.6) + yum (~> 3.10.0) diff --git a/cookbooks/cdo-apps/attributes/default.rb b/cookbooks/cdo-apps/attributes/default.rb index bd818044a3525..8fb230849bc96 100644 --- a/cookbooks/cdo-apps/attributes/default.rb +++ b/cookbooks/cdo-apps/attributes/default.rb @@ -14,3 +14,4 @@ }, 'nginx_enabled' => true } +default['omnibus_updater']['version'] = '12.7.2' diff --git a/cookbooks/cdo-apps/metadata.rb b/cookbooks/cdo-apps/metadata.rb index 9c6403b448acd..876b6bb3bac09 100644 --- a/cookbooks/cdo-apps/metadata.rb +++ b/cookbooks/cdo-apps/metadata.rb @@ -4,7 +4,7 @@ license 'All rights reserved' description 'Installs/Configures cdo-apps' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.2.17' +version '0.2.19' depends 'apt' depends 'build-essential' diff --git a/cookbooks/cdo-apps/templates/default/crontab.erb b/cookbooks/cdo-apps/templates/default/crontab.erb index 110400341b44c..ce2e4c76f164f 100644 --- a/cookbooks/cdo-apps/templates/default/crontab.erb +++ b/cookbooks/cdo-apps/templates/default/crontab.erb @@ -1,96 +1,97 @@ <% -require 'shellwords' + require 'shellwords' -$crontab = [] + $crontab = [] -def home_dir(*paths) - File.join '/home', node[:current_user], *paths -end - -def deploy_dir(*paths) - home_dir node.chef_environment, *paths -end - -def bin_dir(*paths) - deploy_dir 'bin', *paths -end + def home_dir(*paths) + File.join '/home', node[:current_user], *paths + end -def dashboard_dir(*paths) - deploy_dir 'dashboard', *paths -end + def deploy_dir(*paths) + home_dir node.chef_environment, *paths + end -def pegasus_dir(*paths) - deploy_dir 'pegasus', *paths -end + def bin_dir(*paths) + deploy_dir 'bin', *paths + end -def shared_dir(*paths) - deploy_dir 'shared', *paths -end + def dashboard_dir(*paths) + deploy_dir 'dashboard', *paths + end -def cronjob(params) - time = params[:at].to_s - action = params[:do].to_s + def pegasus_dir(*paths) + deploy_dir 'pegasus', *paths + end - notify = params[:notify].to_s - action = "BUNDLE_GEMFILE=#{deploy_dir('Gemfile')} bundle exec #{bin_dir('cronjob')} #{action.shellescape} #{notify}".strip + def shared_dir(*paths) + deploy_dir 'shared', *paths + end - $crontab << "#{time} #{action}" -end + def cronjob(params) + time = params[:at].to_s + action = params[:do].to_s -def crontab() - $crontab.join("\n") -end + notify = params[:notify].to_s + action = "BUNDLE_GEMFILE=#{deploy_dir('Gemfile')} bundle exec #{bin_dir('cronjob')} #{action.shellescape} #{notify}".strip -# for multi-instance envs (ie production) there should be one daemon, -# so cronjobs that run once per environment go here (standalone env -# instances are all their own daemon) -if node['cdo-apps']['daemon'] - unless node.chef_environment == 'production' # non-production daemons - cronjob at:'@reboot', do:"#{deploy_dir('bin','solr-server')} > #{pegasus_dir('log','solr.log')} 2>&1" + $crontab << "#{time} #{action}" end - if node.chef_environment == 'staging' && node.name == 'staging' # 'real' staging only - cronjob at:'@reboot', do:home_dir('.dropbox-dist', 'dropboxd') - cronjob at:'*/5 * * * *', do:deploy_dir('bin', 'import_google_sheets') - cronjob at:'*/2 * * * *', do:deploy_dir('bin','run_server_generate_pdfs'), notify:'dev+crontab@code.org' - cronjob at:'*/2 * * * *', do:pegasus_dir('sites','virtual','run_server_generate_curriculum_pdfs'), notify:'dev+crontab@code.org' - cronjob at:'*/2 * * * *', do:pegasus_dir('sites','virtual','collate_pdfs'), notify:'dev+crontab@code.org' - cronjob at:'*/2 * * * *', do:dashboard_dir('bin','build_scripts'), notify:'dev+crontab@code.org' - cronjob at:'*/5 * * * *', do:deploy_dir('bin','fetch-external-resources'), notify:'dev+crontab@code.org' - cronjob at:'30 16 * * *', do:deploy_dir('bin', 'cron', 'update_dotd') + def crontab() + $crontab.join("\n") end - if node.chef_environment == 'production' # production daemon - cronjob at:'20 */2 * * *', do:deploy_dir('bin', 'cron', 'activity-monitor') - cronjob at:'5 6 * * *', do:deploy_dir('bin', 'send_workshop_reminder_emails') - cronjob at:'15 16 * * *', do:dashboard_dir('bin','scheduled_ops_emails') - cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'index-users-in-solr') - cronjob at:'25 7 * * *', do:deploy_dir('bin', 'update-hoc-map') + # for multi-instance envs (ie production) there should be one daemon, + # so cronjobs that run once per environment go here (standalone env + # instances are all their own daemon) + if node['cdo-apps']['daemon'] + unless node.chef_environment == 'production' # non-production daemons + cronjob at:'@reboot', do:"#{deploy_dir('bin','solr-server')} > #{pegasus_dir('log','solr.log')} 2>&1" + end + + if node.chef_environment == 'staging' && node.name == 'staging' # 'real' staging only + cronjob at:'@reboot', do:home_dir('.dropbox-dist', 'dropboxd') + cronjob at:'*/5 * * * *', do:deploy_dir('bin', 'import_google_sheets') + cronjob at:'*/2 * * * *', do:deploy_dir('bin','run_server_generate_pdfs'), notify:'dev+crontab@code.org' + cronjob at:'*/2 * * * *', do:pegasus_dir('sites','virtual','run_server_generate_curriculum_pdfs'), notify:'dev+crontab@code.org' + cronjob at:'*/2 * * * *', do:pegasus_dir('sites','virtual','collate_pdfs'), notify:'dev+crontab@code.org' + cronjob at:'*/2 * * * *', do:dashboard_dir('bin','build_scripts'), notify:'dev+crontab@code.org' + cronjob at:'*/5 * * * *', do:deploy_dir('bin','fetch-external-resources'), notify:'dev+crontab@code.org' + cronjob at:'30 16 * * *', do:deploy_dir('bin', 'cron', 'update_dotd') + end + + if node.chef_environment == 'production' # production daemon + cronjob at:'20 */2 * * *', do:deploy_dir('bin', 'cron', 'activity-monitor') + cronjob at:'5 6 * * *', do:deploy_dir('bin', 'send_workshop_reminder_emails') + cronjob at:'15 16 * * *', do:dashboard_dir('bin','scheduled_ops_emails') + cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'index-users-in-solr') + cronjob at:'25 7 * * *', do:deploy_dir('bin', 'update-hoc-map') + end + + # 'daemons' in all environments + cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'cron', 'process_forms') + cronjob at:'35 * * * *', do:deploy_dir('bin', 'cron', 'analyze_hoc_activity') + cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'deliver_poste_messages') + cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'cron', 'geocode_hoc_activity') + cronjob at:'55 8 * * *', do:deploy_dir('bin', 'cron', 'ops_data_pull') + cronjob at:'45 5 * * *', do:deploy_dir('bin', 'cron', 'admin_stats') + cronjob at:'40 4 * * *', do:deploy_dir('bin', 'cron', 'funometer') + cronjob at:'30 6 * * *', do:deploy_dir('bin', 'cron', 'admin_progress') + cronjob at:'10 7 * * *', do:deploy_dir('bin', 'cron', 'retention_stats') + cronjob at:'*/1 * * * *', do:deploy_dir('aws', 'ci_build'), notify: 'dev+build@code.org' end - # 'daemons' in all environments - cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'cron', 'process_forms') - cronjob at:'35 * * * *', do:deploy_dir('bin', 'cron', 'analyze_hoc_activity') - cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'deliver_poste_messages') - cronjob at:'*/1 * * * *', do:deploy_dir('bin', 'cron', 'geocode_hoc_activity') - cronjob at:'55 8 * * *', do:deploy_dir('bin', 'cron', 'ops_data_pull') - cronjob at:'45 5 * * *', do:deploy_dir('bin', 'cron', 'admin_stats') - cronjob at:'40 4 * * *', do:deploy_dir('bin', 'cron', 'funometer') - cronjob at:'30 6 * * *', do:deploy_dir('bin', 'cron', 'admin_progress') - cronjob at:'10 7 * * *', do:deploy_dir('bin', 'cron', 'retention_stats') -end - -# cronjobs that run on all instances in all environments go here: - -# Restart Pegasus and dashboard every 8 hours at 0, 8, 16 UTC (12AM, 8AM, 4PM). -# The restart interval from from every 4 hours on 2016/4/26. After recent memory -# leak fixes this is probably no longer necessary, but we are keeping it at this -# level until we have chance to confirm non-leakage over longer intervals. -cronjob at:"#{rand(20)} */8 * * *", do:'service dashboard upgrade && service pegasus upgrade' - -cronjob at:"#{rand(60)} * * * *", do:"#{deploy_dir('bin','upload-logs-to-s3')} dashboard pegasus" - -cronjob at:'@reboot', do:'chef-client' + # cronjobs that run on all instances in all environments go here: + + # Restart Pegasus and dashboard every 8 hours at 0, 8, 16 UTC (12AM, 8AM, 4PM). + # The restart interval from from every 4 hours on 2016/4/26. After recent memory + # leak fixes this is probably no longer necessary, but we are keeping it at this + # level until we have chance to confirm non-leakage over longer intervals. + cronjob at:"#{rand(20)} */8 * * *", do:'service dashboard upgrade && service pegasus upgrade' + + cronjob at:"#{rand(60)} * * * *", do:"#{deploy_dir('bin','upload-logs-to-s3')} dashboard pegasus" + + cronjob at:'@reboot', do:'chef-client' %> # # node: <%= node.name %> diff --git a/cookbooks/cdo-apps/test/integration/nginx/serverspec/ruby_spec.rb b/cookbooks/cdo-apps/test/integration/daemon/serverspec/ruby_spec.rb similarity index 100% rename from cookbooks/cdo-apps/test/integration/nginx/serverspec/ruby_spec.rb rename to cookbooks/cdo-apps/test/integration/daemon/serverspec/ruby_spec.rb diff --git a/dashboard/app/controllers/levels_controller.rb b/dashboard/app/controllers/levels_controller.rb index 196e89d87b754..61cb72fefd474 100644 --- a/dashboard/app/controllers/levels_controller.rb +++ b/dashboard/app/controllers/levels_controller.rb @@ -53,10 +53,12 @@ def edit_blocks toolbox_blocks = @level.complete_toolbox(type) # Levels which support solution blocks use those blocks as the - # toolbox for required and recommended block editors + # toolbox for required and recommended block editors, plus the + # special "pick one" block if @level.respond_to?("get_solution_blocks") && (type == 'required_blocks' || type == 'recommended_blocks') - toolbox_blocks = "