add graphql linter and cleanup some groovy scripts

fixes: CCI-115

Test-Plan:
do these steps in one PS:
1 - make some changes that would fail the graphql
2 - add the skip-ci flag in commit message to skip old jenkins
3 - set the GERGICH_PUBLISH = 1 in the main Jenkinsfile
4 - look at patchset 9 for these

Change-Id: I9f3a7028cac5c659d8e3a3b8c8e6f6fbe5423bc2
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/218401
Reviewed-by: S. Jacob Powell <spowell@instructure.com>
Reviewed-by: James Butters <jbutters@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Tested-by: Jenkins
QA-Review: Rex Fleischer <rfleischer@instructure.com>
Product-Review: Rex Fleischer <rfleischer@instructure.com>
This commit is contained in:
Rex Fleischer 2019-11-22 12:57:11 -08:00
parent 842f4be312
commit f9edb9a513
7 changed files with 139 additions and 55 deletions

47
Jenkinsfile vendored
View File

@ -18,45 +18,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
def fullSuccessName(name) {
return "_successes/${env.GERRIT_CHANGE_NUMBER}-${env.GERRIT_PATCHSET_NUMBER}-${name}-success"
}
def hasSuccess(name) {
copyArtifacts(filter: "_successes/*",
optional: true,
projectName: '/${JOB_NAME}',
parameters: "GERRIT_CHANGE_NUMBER=${env.GERRIT_CHANGE_NUMBER},GERRIT_PATCHSET_NUMBER=${GERRIT_PATCHSET_NUMBER}",
selector: lastCompleted())
if (fileExists("_successes")) {
archiveArtifacts(artifacts: "_successes/*",
projectName: '/${JOB_NAME}')
}
return fileExists(fullSuccessName(name))
}
def saveSuccess(name) {
def success_name = fullSuccessName(name)
sh "mkdir -p _successes"
sh "echo 'success' >> ${success_name}"
archiveArtifacts(artifacts: "_successes/*",
projectName: '/${JOB_NAME}')
echo "===> success saved /${env.JOB_NAME}: ${success_name}"
}
// runs the body if it has not previously succeeded.
// if you don't want the success of the body to mark the
// given name as successful, pass in save = false.
def skipIfPreviouslySuccessful(name, save = true, body) {
if (hasSuccess(name)) {
echo "===> block already successful, skipping: ${fullSuccessName(name)}"
} else {
echo "===> running block: ${fullSuccessName(name)}"
body.call()
if (save) saveSuccess(name)
}
}
def build_parameters = [
string(name: 'GERRIT_REFSPEC', value: "${env.GERRIT_REFSPEC}"),
string(name: 'GERRIT_EVENT_TYPE', value: "${env.GERRIT_EVENT_TYPE}"),
@ -81,10 +42,16 @@ def runBuildImageMaybe(save_success, block) {
echo "skip building image requested"
}
else {
skipIfPreviouslySuccessful("build-and-push-image", save_success, block)
def skips = load 'build/new-jenkins/groovy/successes.groovy'
skips.skipIfPreviouslySuccessful("build-and-push-image", save_success, block)
}
}
def skipIfPreviouslySuccessful(name, block) {
def skips = load 'build/new-jenkins/groovy/successes.groovy'
skips.skipIfPreviouslySuccessful(name, true, block)
}
pipeline {
agent { label 'canvas-docker' }

View File

@ -1,3 +1,21 @@
/*
* Copyright (C) 2019 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// If the migrated images are not found, then it builds from database base images
def loadMigratedImages() {
dockerCacheLoad(image: "$POSTGRES_CACHE_TAG")

View File

@ -1,5 +1,22 @@
/*
* Copyright (C) 2019 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// TODO: until we get this into a shared library,
// TODO: until we get this into a shared library,
// i dont think we can hold flags in a variable
// TODO: maybe add a set of allowed flags so we know if we fat-finger something?

View File

@ -1,5 +1,20 @@
/*
* Copyright (C) 2019 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
def withGerritCredentials(block) {
withCredentials([
@ -18,4 +33,4 @@ def fetchFromGerrit(String repo, String path, String customRepoDestination = nul
})
}
return this
return this

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2019 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
def fullSuccessName(name) {
return "_successes/${env.GERRIT_CHANGE_NUMBER}-${env.GERRIT_PATCHSET_NUMBER}-${name}-success"
}
def hasSuccess(name) {
copyArtifacts(filter: "_successes/*",
optional: true,
projectName: '/${JOB_NAME}',
parameters: "GERRIT_CHANGE_NUMBER=${env.GERRIT_CHANGE_NUMBER},GERRIT_PATCHSET_NUMBER=${GERRIT_PATCHSET_NUMBER}",
selector: lastCompleted())
if (fileExists("_successes")) {
archiveArtifacts(artifacts: "_successes/*",
projectName: '/${JOB_NAME}')
}
return fileExists(fullSuccessName(name))
}
def saveSuccess(name) {
def success_name = fullSuccessName(name)
sh "mkdir -p _successes"
sh "echo 'success' >> ${success_name}"
archiveArtifacts(artifacts: "_successes/*",
projectName: '/${JOB_NAME}')
echo "===> success saved /${env.JOB_NAME}: ${success_name}"
}
// runs the body if it has not previously succeeded.
// if you don't want the success of the body to mark the
// given name as successful, pass in save = false.
def skipIfPreviouslySuccessful(name, save = true, body) {
if (hasSuccess(name)) {
echo "===> block already successful, skipping: ${fullSuccessName(name)}"
} else {
echo "===> running block: ${fullSuccessName(name)}"
body.call()
if (save) saveSuccess(name)
}
}
return this

View File

@ -2,17 +2,19 @@
set -x -o errexit -o errtrace -o nounset -o pipefail
inputs=()
inputs+=("--volume $WORKSPACE/.git:/usr/src/app/.git")
inputs+=("--env GERGICH_PUBLISH=$GERGICH_PUBLISH")
inputs+=("--env GERGICH_KEY=$GERGICH_KEY")
inputs+=("--env GERRIT_HOST=$GERRIT_HOST")
inputs+=("--env GERRIT_PROJECT=$GERRIT_PROJECT")
inputs+=("--env GERRIT_BRANCH=$GERRIT_BRANCH")
# the GERRIT_REFSPEC is required for the commit message to actually
# send things to gergich
cat <<EOF | docker run --interactive \
--volume $WORKSPACE/.git:/usr/src/app/.git \
--env GERGICH_PUBLISH=$GERGICH_PUBLISH \
--env GERRIT_REFSPEC=$GERRIT_REFSPEC \
--env GERGICH_KEY=$GERGICH_KEY \
--env GERRIT_HOST=$GERRIT_HOST \
--env GERRIT_PROJECT=$GERRIT_PROJECT \
--env GERRIT_BRANCH=$GERRIT_BRANCH \
$PATCHSET_TAG /bin/bash -
inputs+=("--env GERRIT_REFSPEC=$GERRIT_REFSPEC")
cat <<EOF | docker run --interactive ${inputs[@]} $PATCHSET_TAG /bin/bash -
set -ex
# the linters expect this to be here else it will just look at master
@ -27,11 +29,18 @@ bundle exec ruby script/rlint
bundle exec ruby script/eslint
bundle exec ruby script/lint_commit_message
RAILS_ENV=test bundle exec rails graphql:schema
# if the generated file is different from the checked in file, fail
if ! git diff --exit-code schema.graphql; then
message="GraphQL Schema changes are not checked in: run 'bundle exec rails graphql:schema' to generate graphql.schema file"
gergich comment "{\"path\":\"schema.graphql\",\"position\":1,\"severity\":\"error\",\"message\":\"\$message\"}"
fi
# this is here to remind us that we need to add this during compile once we
# figure out the write issues with a mounted volume of gergich
# bundle exec gergich capture custom:./build/gergich/compile_assets:Gergich::CompileAssets "rake canvas:compile_assets"
gergich comment '{"path":"gergich-test.rb","position":3,"severity":"info","message":"from-new-jenkins"}'
gergich comment '{"path":"/COMMIT_MSG","position":0,"severity":"info","message":"from-new-jenkins"}'
gergich status
if [[ "$GERGICH_PUBLISH" == "1" ]]; then

View File

@ -2,7 +2,7 @@
set -x -o errexit -o errtrace -o nounset -o pipefail
if [[ -z "${MASTER_BOUNCER_KEY}" ]]; then
if [[ -z "${MASTER_BOUNCER_KEY-}" ]]; then
echo "MASTER_BOUNCER_KEY not set. cannot run master_bouncer check"
exit 0
fi