From e4ea5bcfcf9a4bd84e7d5f8e0e063053d9ea5bf0 Mon Sep 17 00:00:00 2001 From: Brian Stinson Date: Mar 02 2018 16:43:33 +0000 Subject: Move the pipeline to its own project --- diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 0000000..696c3b9 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,17 @@ +FROM registry.fedoraproject.org/f27/s2i-core:latest + +RUN dnf -y install findutils git ruby-devel @c-development redhat-rpm-config +RUN gem install ascii_binder + +RUN git config --global user.email 'docs@fedoraproject.org' +RUN git config --global user.name 'Fedora Docs' + +ENV REPO https://pagure.io/fedora-docs/docs-fp-o +ENV BRANCH master + +RUN mkdir /docs && chgrp -R 0 /docs && chmod +x /docs && chmod -R g=u /docs +WORKDIR /docs +COPY ./s2i/bin/ $STI_SCRIPTS_PATH + +USER 1001 +CMD echo "Done" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4a34b6e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2018 Brian Stinson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c2c1613 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# asciidoc s2i Builder + +## Usage + +This builder is used in openshift to generate sites automatically. But, you can +also run the builder on your own workstation. + +### Prerequisites +You need the `source-to-image` package on your workstation to build an output +image. + +``` +$ dnf -y install source-to-image +``` + +### Getting/building the container + +``` +$ docker pull bstinsonmhk/docs-fpo-build +``` + +Or build it yourself + +``` +$ docker build --tag /docs-fpo-build -f Dockerfile.build . +``` + +### Building the master docs.fedoraproject.org Site: +``` +# We need to do the magic --exclude='' flag here, so the .git directory isn't +# stripped out by s2i + +$ s2i build https://pagure.io/fedora-docs/docs-fp-o --exclude='' bstinsonmhk/docs-fpo-build +``` + +### Building a pull request on the install-guide: + +``` + +# This builds pull-request 1 on the install-guide and puts it in the output +# image. Feel free to try against the other fedora-docs repos as well! If you +# leave off the PR= variable the builder will build the master branch. + +$ s2i build https://pagure.io/fedora-docs/install-guide -e "PR=1" --exclude='' bstinsonmhk/docs-fpo-build +``` + +### Running the built image + +``` +$ docker run -d -p 8080:8080 +``` + +et voilà ! Visit http://localhost:8080 to explore the site. diff --git a/docs-build-pipeline.yaml b/docs-build-pipeline.yaml new file mode 100644 index 0000000..05bf625 --- /dev/null +++ b/docs-build-pipeline.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: BuildConfig +metadata: + annotations: + pipeline.alpha.openshift.io/uses: '[{"name": "docs-build", "namespace": "fedora-docs", "kind": + "DeploymentConfig"}]' + creationTimestamp: null + labels: + app: jenkins-pipeline-development + name: development-pipeline + template: application-template-development-pipeline + name: development-pipeline +spec: + output: {} + postCommit: {} + resources: {} + runPolicy: Serial + source: + type: None + strategy: + jenkinsPipelineStrategy: + jenkinsfile: |- + node('') { + stage ('build-artifact'){ + openshiftBuild(buildConfig: 'docs-ci-artifact', showBuildLogs: 'true', namespace: 'fedora-docs') + } + stage('deploy'){ + openshiftDeploy(deploymentConfig: 'docs-ci-runtime', namespace: 'fedora-docs') + } + } + type: JenkinsPipeline + triggers: + - github: + secret: secret101 + type: GitHub + - generic: + secret: secret101 + type: Generic +status: + lastVersion: 0 diff --git a/docs-build-pr.yaml b/docs-build-pr.yaml new file mode 100644 index 0000000..a4509ff --- /dev/null +++ b/docs-build-pr.yaml @@ -0,0 +1,219 @@ +apiVersion: v1 +kind: Template +metadata: + name: docs-pr +objects: +- kind: BuildConfig + apiVersion: v1 + metadata: + name: "${NAME}-pr" + annotations: + name: "${NAME}-pr" + pipeline.alpha.openshift.io/uses: '[{"name": "${NAME}-pr", "namespace": "${NAMESPACE}", "kind": "DeploymentConfig"}]' + spec: + strategy: + runPolicy: Parallel + jenkinsPipelineStrategy: + jenkinsfile: |- + try { + node('') { + properties([ + [ + $class: 'BuildConfigProjectProperty', + name: '', + namespace: '', + resourceVersion: '', + uid: '' + ], + parameters([ + string(defaultValue: "", description: "", name: "REPO"), + string(defaultValue: "", description: "", name: "BRANCH"), + string(defaultValue: "", description: "", name: "PR") + ]) + ]) + + stage('env') { + env.REPO_SHORTNAME = params.REPO.replaceAll('/','-') + sh 'env' + println "${REPO}" + } + + stage('Repo OS Resources'){ + try{ + sh "oc get is/${REPO_SHORTNAME}-artifact" + } catch (Exception e) { + println "Imagestream for ${REPO_SHORTNAME} not found. creating..." + openshiftCreateResource(jsonyaml:''' + apiVersion: v1 + kind: ImageStream + metadata: + name: ${REPO_SHORTNAME}-artifact + annotations: + description: The artifacts built + ''') + } + + try{ + sh "oc get bc/${REPO_SHORTNAME}" + } catch (Exception e) { + println "Buildconfig for ${REPO_SHORTNAME} not found. creating..." + openshiftCreateResource(jsonyaml:''' + kind: BuildConfig + apiVersion: v1 + metadata: + name: ${REPO_SHORTNAME} + labels: + app: ${REPO_SHORTNAME} + spec: + output: + to: + kind: ImageStreamTag + name: ${REPO_SHORTNAME}-artifact:latest + source: + type: Git + git: + uri: https://pagure.io/${REPO_SHORTNAME} + ref: master + strategy: + type: Source + sourceStrategy: + from: + kind: ImageStreamTag + namespace: ${NAMESPACE} + name: docs-fpo-build:latest''') + + } + } + + stage('build') { + openshiftBuild(buildConfig: '${REPO_SHORTNAME}', showBuildLogs: 'true', env: [[name: 'PR', value: env.PR]]) + openshiftTag(sourceStream: '${REPO_SHORTNAME}-artifact', sourceTag: 'latest', destinationStream: '${REPO_SHORTNAME}-artifact', destinationTag: "pr/$PR") + } + + + stage('PR OS Resources') { + + try{ + sh "oc get svc/${REPO_SHORTNAME}-pr-${PR}" + } catch (Exception e) { + println "SVC not found. creating..." + openshiftCreateResource(jsonyaml:''' + kind: Service + apiVersion: v1 + metadata: + name: ${REPO_SHORTNAME}-pr-${PR} + labels: + name: ${REPO_SHORTNAME}-pr-${PR} + spec: + ports: + - name: web + port: 8080 + targetPort: 8080 + selector: + name: ${REPO_SHORTNAME}-pr-${PR}''') + } + + try{ + sh "oc get route/${REPO_SHORTNAME}-pr-${PR}" + } catch (Exception e){ + println "Route not found. creating..." + openshiftCreateResource(jsonyaml:''' + kind: Route + apiVersion: v1 + metadata: + name: ${REPO_SHORTNAME}-pr${PR} + labels: + name: ${REPO_SHORTNAME}-pr-${PR} + spec: + to: + kind: Service + name: ${REPO_SHORTNAME}-pr-${PR}''') + } + + try{ + sh "oc get dc/${REPO_SHORTNAME}-pr-${PR}" + } catch (Exception e){ + println "DC not found, creating..." + openshiftCreateResource(jsonyaml:''' + kind: DeploymentConfig + apiVersion: v1 + metadata: + name: ${REPO_SHORTNAME}-pr-${PR} + labels: + name: ${REPO_SHORTNAME}-pr-${PR} + spec: + strategy: + type: Rolling + replicas: 1 + selector: + name: ${REPO_SHORTNAME}-pr-${PR} + triggers: + - type: ImageChange + imageChangeParams: + automatic: false + containerNames: + - ${REPO_SHORTNAME}-artifact + from: + kind: ImageStreamTag + namespace: ${NAMESPACE} + name: ${REPO_SHORTNAME}-artifact:pr/${PR} + template: + metadata: + name: ${REPO_SHORTNAME}-pr-${PR} + labels: + name: ${REPO_SHORTNAME}-pr-${PR} + spec: + containers: + - name: ${REPO_SHORTNAME}-artifact + image: "" + ports: + - containerPort: 8080 + readinessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 3 + httpGet: + path: / + port: 8080 + livenessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 30 + httpGet: + path: / + port: 8080 + resources: + limits: + memory: 512Mi''') + } + } + + stage('Deploy'){ + openshiftDeploy(depCfg: "${REPO_SHORTNAME}-pr-${PR}") + } + + stage('Wait for input') { + input "Cleanup?" + + openshiftDeleteResourceByLabels(types: "dc,svc,route,po,rc", keys: "name", values: "${REPO_SHORTNAME}-pr-${PR}") + } + } + } catch (err) { + echo "in catch block" + echo "Caught: ${err}" + currentBuild.result = 'FAILURE' + throw err + } + type: JenkinsPipeline + triggers: + - github: + secret: secret101 + type: GitHub + - generic: + secret: secret101 + type: Generic +parameters: + - name: NAME + displayName: The name of the toplevel project in pagure + value: fedora-docs + - name: NAMESPACE + displayName: The openshift namespace to use + value: fedora-docs diff --git a/docs-build.json b/docs-build.json new file mode 100644 index 0000000..796981f --- /dev/null +++ b/docs-build.json @@ -0,0 +1,227 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "name": "docs-fpo-build" + }, + "message": "The following service(s) have been created in your project: ${NAME}.", + "labels": { + "template": "docs-fpo-build" + }, + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "${NAME}", + "annotations": { + "description": "Exposes and load balances the application pods" + } + }, + "spec": { + "ports": [ + { + "name": "web", + "port": 8080, + "targetPort": 8080 + } + ], + "selector": { + "name": "${NAME}" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "${NAME}" + }, + "spec": { + "host": "${APPLICATION_DOMAIN}", + "to": { + "kind": "Service", + "name": "${NAME}" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${NAME}-artifact", + "annotations": { + "description": "Keeps track of changes in the application image" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${NAME}-artifact", + "annotations": { + "description": "Defines how to build the application" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}" + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "from": { + "kind": "ImageStreamTag", + "namespace": "${NAMESPACE}", + "name": "docs-fpo-build:latest" + }, + "env": [] + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${NAME}-artifact:latest" + } + } + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${NAME}-runtime", + "annotations": { + "description": "Defines how to deploy the application server" + } + }, + "spec": { + "strategy": { + "type": "Rolling" + }, + "replicas": 1, + "selector": { + "name": "${NAME}" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": false, + "containerNames": [ + "${NAME}-artifact" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "fedora-docs", + "name": "${NAME}-artifact:latest" + } + } + } + ], + "template": { + "metadata": { + "name": "${NAME}", + "labels": { + "name": "${NAME}" + } + }, + "spec": { + "containers": [ + { + "name": "${NAME}-artifact", + "image": " ", + "ports": [ + { + "containerPort": 8080 + } + ], + "readinessProbe": { + "timeoutSeconds": 3, + "initialDelaySeconds": 3, + "httpGet": { + "path": "/", + "port": 8080 + } + }, + "livenessProbe": { + "timeoutSeconds": 3, + "initialDelaySeconds": 30, + "httpGet": { + "path": "/", + "port": 8080 + } + }, + "resources": { + "limits": { + "memory": "${MEMORY_LIMIT}" + } + } + } + ] + } + } + } + } + ], + "parameters": [ + { + "name": "NAME", + "displayName": "Name", + "description": "The name assigned to all of the frontend objects defined in this template.", + "required": true, + "value": "docs-ci" + }, + { + "name": "NAMESPACE", + "displayName": "Namespace", + "description": "The OpenShift Namespace where the ImageStream resides.", + "required": true, + "value": "fedora-docs" + }, + { + "name": "MEMORY_LIMIT", + "displayName": "Memory Limit", + "description": "Maximum amount of memory the container can use.", + "required": true, + "value": "512Mi" + }, + { + "name": "SOURCE_REPOSITORY_URL", + "displayName": "Git Repository URL", + "description": "The URL of the repository with your application source code.", + "required": true, + "value": "https://pagure.io/forks/bstinson/fedora-docs/docs-fp-o.git" + }, + { + "name": "SOURCE_REPOSITORY_REF", + "displayName": "Git Reference", + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "value": "add-dockerfile" + }, + { + "name": "CONTEXT_DIR", + "displayName": "Context Directory", + "description": "Set this to the relative path to your project if it is not in the root of your repository." + }, + { + "name": "APPLICATION_DOMAIN", + "displayName": "Application Hostname", + "description": "The exposed hostname, if left blank a value will be defaulted.", + "value": "" + }, + { + "name": "GENERIC_WEBHOOK_SECRET", + "displayName": "Generic Webhook Secret", + "description": "A secret string used to configure the Generic webhook.", + "generate": "expression", + "from": "[a-zA-Z0-9]{40}" + } + ] +} diff --git a/s2i/bin/assemble b/s2i/bin/assemble new file mode 100755 index 0000000..262d814 --- /dev/null +++ b/s2i/bin/assemble @@ -0,0 +1,37 @@ +#!/bin/bash + +mv /tmp/src /docs/ + +pushd /docs/src + +echo " -----> Beginning Environment." +env + +for remote in `git branch -r | grep -v master`; do git branch --track ${remote#origin/} $remote; done +git fetch --all + +if [ -v PR ]; then + echo " -----> Building a PR against the base repo." + git fetch origin pull/${PR}/head:proposed + + git checkout proposed + git show-ref --head --dereference + + # This is a fairly nasty thing to do, but asciibinder always checks out + # -master- and we don't want to try an auto-merge at this stage, that's for + # people to do. Resetting the local master to the head of the PR will make + # asciibinder happy + + echo " -----> Resetting master" + git branch -f master HEAD + git show-ref --head --dereference + +fi + +if [ -f builder.sh ]; then + echo " -----> Building a repo with a builder.sh" + ./builder.sh +fi + +echo " -----> Packaging" +asciibinder package diff --git a/s2i/bin/run b/s2i/bin/run new file mode 100755 index 0000000..6a574ec --- /dev/null +++ b/s2i/bin/run @@ -0,0 +1,3 @@ +#!/bin/bash + +exec ruby -run -ehttpd /docs/src/_package/main -p8080