diff --git a/.gitignore b/.gitignore index 59e33e561b31..c1d7ec36dfda 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,7 @@ hack/config-local.sh tags .Gopkg.* .GeneratedDockerfile +.gradle +hack/gen-swagger-doc/*.adoc +hack/gen-swagger-doc/*.md +hack/gen-swagger-doc/html5 diff --git a/.travis.yml b/.travis.yml index b6f6d481721e..19118bf5b8fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,7 @@ script: - if [[ $TRAVIS_REPO_SLUG == "kubevirt/kubevirt" ]]; then $HOME/gopath/bin/goveralls -service=travis-ci -package=./pkg/... -ignore=$(find -name generated_mock*.go -printf "%P\n" | paste -d, -s) ; else make test; fi +- make apidocs cache: directories: @@ -73,8 +74,15 @@ deploy: on: tags: true repo: kubevirt/kubevirt +- provider: script + skip_cleanup: true + script: bash hack/gen-swagger-doc/deploy.sh + on: + branch: master + go: 1.8.3 env: global: - secure: qU6IqYNN7P9UiQjvgfXdqvbvD1RLIP4a6uH9fX4Dx3UFXmutXE38/RIWhOtIAzDz8QHhm2l8vfefaC9VwGJI3XPv6gfKCCRPYj+0EKn0E7mJBM0uk7NRiujLg9Kh2zFCkYJT4Q91L39/STbDdoSBLHjwuMKUPOQlysOr8sQS6JT1xb7qJ/Vhcgy7Ex0jba4qHiDsLlJQulOE7YS5HxfwUN+cN9maQjFZNM7NpLf3YFqZ1Yq7hnBxXjpteMWSuGsCsSE2hlKwHvtYhcMoSWR7dw3x25XapwBI5YB5z8CEZvWsHbx9qnbe5VGMBVMubWw9xjQkAImKp2PFceMVRSgx01ufZBf434jLYA1+OmBgow15iGJhy9icxSOvXn0aA46rhzGkFHsd4MDd04bO8S1KXvr9ALfU8OP+VqG9Gnt0mCV+qrT1JpYyR0NrS3uMd1R7F+o8CL1Mf5V/UGkHsfdHWSgBqKfmHaR5xEmp5M2wHHkgD9PFedimyUZDuhJPAu26UNeCHxhzq3+sReFsdPQbVA/eRvXNu5Fj1qNtIaCj/2L31AeR7SpCDSgYrnBVAojSjNiVYD9fSIT7TGsZ9oNaqGfCh08hbVGrxD4qJuyzkJPOkdhohfPS0MhYMf9GJ36qCn/odOdchOl2RyKOt5NiWN+qrRG4aXXKcUvO2RVuTJo= - secure: ipzpBip/KzzrMXy0SjvnpxMhj95ygcAqI7zpth8L0b7nBIsdyfFZj8MoE4PNiaG+YQdK3eVyLjDU3U67HzrviCLHeWcCaCqzIdNes9ig2kuL65LcHom0YmfWtZY3WKwqtu2Cr4UW+16FPecWEg0pNRBrI/u0Yzmn1K/Ll46iycndtyCU4uysPeN0JBK7Ht6J4YUlhZQ0rnA2p+TpH3lwSW63qmZgwGOsixwAMe35vXrPZVPBk2ROG6+MfToFcU+5h+snEOenCnyVyfxP5UqNVRE/ZAmcWBSIo7/FyGJ3/VMJMCBFqXLJAU5DF9N182p7VwQcMctq4Iba1Yjmezdit2f5F2KPtPttWXV0fqy9zB1/Hlbz41htaAwSrsnsFaN33W+hdbFWC9vGgXSy71RngPBTaq/rwb2125CKxoehcUijAavFJMt8926HrHXztWTjyNSerms9EGoJjDspDmySNg4hMOrTtJbE+L+1Ze5I7ZfgfFU9oACM2SffpbtKAnqEbi8+UkNi33MntNSSvULfE/RFRYbl7ld54CNTUFQinLThLnRCtyVQN0VadA554qf+4HTXgvW6ifYljHKUkl6QEkuf0GCDZg3R8sIkvkqf7jpDwdq9+wErLao2z+SW1LV/vnHQxuKZTBTquGIhroehO4lljUdeE8BU0P+S+n+nzFg= + - secure: pS1N+T7f20B9PJ2S6e4Bc0z0vK6wnUgtGrs1982iXYocVZZtL6LreXYV/9a5ANrykLx+/qeRxbR4FTknfJwsmm2MX1WN7FIEtp7wGxt5uU0Q+b5pERbgUL8amkvhc6Hj9eWn59fbEKSmAEeMupeYydPPCFJp8oumEEP6szb0zCj7LQPWxhEMtVLY2U8d3WbkhBoxC1Bv5kTOajaiyuwjgiJd3yvR6WfNOQUL167TCoyzRDoe7jUSZ9EScyDRg7mC2Nk2o4vzZwmaz8QjO6T6f2za95t7/kxhYrL7WAfa3POxdhHPP0XX4ZsypU6++hDj0txPAB/ICa55Za6A+BhFrUdGeoYb3T8jtWIF9UDHq6m8yhurtDPooR7VMjkR2ghz4Ol4cv2f1QWv5MGDg4hh9gKgjE+gbbeZyA5+t3l/Zf2HozZQCIDpMpi4EUUS3rCGkr44h0AjiZP9s4QrUY74kpT6GEGluFTlkXar+R3bvnTVY2J4vj6XGdAXHYtAbKI2/yaq20wqkbsC6BKHITcZ/E3eIBh2kc0WD4pdm8MnI0chuuMSkM6ynRDcPNYi235VmhxuUBaNWrkQEHGVOjXJPLB+xMRc6vVxAjV/OFaKXsbPb4aJl1TRJ1RclHAf4Am3SPuiowm8JmODTrmmYkF67rAGILO1oVxwmvwVLAmcJSI= diff --git a/Makefile b/Makefile index e91367798ae5..10dc25b379d3 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,13 @@ generate: sync (cd tools/openapispec/ && go build) tools/openapispec/openapispec --dump-api-spec-path api/openapi-spec/swagger.json +apidocs: generate + docker run -u `stat -c "%u" hack/gen-swagger-doc/` --rm \ + -v ${PWD}:/home/gradle/kubevirt:rw,z \ + -w /home/gradle/kubevirt \ + gradle \ + bash hack/gen-swagger-doc/gen-swagger-docs.sh v1 html + build: checksync fmt vet compile compile: diff --git a/hack/gen-swagger-doc/build.gradle b/hack/gen-swagger-doc/build.gradle new file mode 100644 index 000000000000..dfecf7aa1774 --- /dev/null +++ b/hack/gen-swagger-doc/build.gradle @@ -0,0 +1,35 @@ +buildscript { + repositories { + mavenLocal() + jcenter() + } + + dependencies { + classpath "io.github.swagger2markup:swagger2markup-gradle-plugin:1.3.1" + classpath "org.asciidoctor:asciidoctor-gradle-plugin:1.5.6" + } +} + +apply plugin: 'io.github.swagger2markup' + +convertSwagger2markup { + swaggerInput "./api/openapi-spec/swagger.json" + outputDir file("./") + config = [ + 'swagger2markup.markupLanguage': markupLanguage, + 'swagger2markup.interDocumentCrossReferencesEnabled': true, + ] +} + +apply plugin: 'org.asciidoctor.convert' + +asciidoctor { + sourceDir = file('./') + sources { + // paths.adoc is being renamed to operations.adoc by gen-swagger-docs.sh. + // Keeping it here in case somebody run: gradle convertSwagger2markup asciidoctor + include 'definitions.adoc', 'overview.adoc', 'paths.adoc', 'security.adoc', 'operations.adoc' + } + outputDir = file('./') + attributes 'toc' : 'right' +} diff --git a/hack/gen-swagger-doc/deploy.sh b/hack/gen-swagger-doc/deploy.sh new file mode 100755 index 000000000000..c526d092a548 --- /dev/null +++ b/hack/gen-swagger-doc/deploy.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +GITHUB_FQDN=github.com +API_REF_REPO=kubevirt-incubator/api-reference +API_REF_DIR=/tmp/api-reference + +git clone \ + "https://${API_REFERENCE_PUSH_TOKEN}@${GITHUB_FQDN}/${API_REF_REPO}.git" \ + "${API_REF_DIR}" > /dev/null 2>&1 +rm -rf "${API_REF_DIR}/content/"* +cp -f hack/gen-swagger-doc/html5/content/*.html "${API_REF_DIR}/content/" + +cd "${API_REF_DIR}" + +git config --global user.email "travis@travis-ci.org" +git config --global user.name "Travis CI" + +if git status --porcelain | grep --quiet "^ M" ; +then + git add -A content/*.html + git commit --message "API Reference update by Travis Build ${TRAVIS_BUILD_NUMBER}" + + git push origin master > /dev/null 2>&1 + echo "API Reference updated." +else + echo "API Reference hasn't changed." +fi diff --git a/hack/gen-swagger-doc/gen-swagger-docs.sh b/hack/gen-swagger-doc/gen-swagger-docs.sh new file mode 100755 index 000000000000..fd87beb58cbc --- /dev/null +++ b/hack/gen-swagger-doc/gen-swagger-docs.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# gen-swagger-docs.sh $API_VERSION $OUTPUT_FORMAT +# API_VERSION=v1 +# OUTPUT_FORMAT=html|markdown + +set -o errexit +set -o nounset +set -o pipefail + +VERSION="${1:-v1}" +OUTPUT_FORMAT="${2:-html}" +if [ "$OUTPUT_FORMAT" = "html" ] ; +then + SUFFIX="adoc" + HEADER="=" + LINK1_TEMPLATE="\* \<\<\${VERSION}.\$m\>\>" + LINK_DEFINITIONS="* link:./definitions.html[Types Definition]" + LINK_OPERATIONS="* link:./operations.html[Operations]" + GRADLE_EXTRA_PARAMS="" +elif [ "$OUTPUT_FORMAT" = "markdown" ] ; +then + SUFFIX="md" + HEADER="#" + LINK1_TEMPLATE="\* [\${VERSION}.\$m]\(definitions.md#\${VERSION}-\${m,,}\)" + LINK_DEFINITIONS="* [Types Definition](definitions.md)" + LINK_OPERATIONS="* [Operations](operations.md)" + GRADLE_EXTRA_PARAMS="-PmarkupLanguage=MARKDOWN" +else + echo "Unknown OUTPUT_FORMAT=${OUTPUT_FORMAT}" + exit 1 +fi +WORKDIR="hack/gen-swagger-doc" +GRADLE_BUILD_FILE="$WORKDIR/build.gradle" + + +# Generate *.adoc files from swagger.json +gradle -b $GRADLE_BUILD_FILE $GRADLE_EXTRA_PARAMS convertSwagger2markup --info + +#insert a TOC for top level API objects +buf="${HEADER}${HEADER} Top Level API Objects\n\n" +top_level_models=$(grep '&[A-Za-z]*{},' pkg/api/${VERSION}/types.go | sed 's/.*&//;s/{},//') + +# check if the top level models exist in the definitions.$SUFFIX. If they exist, +# their name will be . +for m in $top_level_models +do + if grep -xq "${HEADER}${HEADER}${HEADER} ${VERSION}.$m" "$WORKDIR/definitions.${SUFFIX}" + then + buf+="$(eval echo $LINK1_TEMPLATE)\n" + fi +done +sed -i "1i $buf" "$WORKDIR/definitions.${SUFFIX}" + +# change the title of paths.adoc from "paths" to "operations" +sed -i "s|${HEADER}${HEADER} Paths|${HEADER}${HEADER} Operations|g" "$WORKDIR/paths.${SUFFIX}" +mv -f "$WORKDIR/paths.${SUFFIX}" "$WORKDIR/operations.${SUFFIX}" + + +# Add links to definitons & operations under overview +cat >> "$WORKDIR/overview.${SUFFIX}" << __END__ +${HEADER}${HEADER} KubeVirt API Reference + +${LINK_DEFINITIONS} +${LINK_OPERATIONS} +__END__ + + +if [ "$OUTPUT_FORMAT" = "html" ] ; +then + # $$ has special meaning in asciidoc, we need to escape it + sed -i 's|\$\$|+++$$+++|g' "$WORKDIR/definitions.adoc" + sed -i '1 i\:last-update-label!:' "$WORKDIR/"*.adoc + + # Generate *.html files from *.adoc + gradle -b $GRADLE_BUILD_FILE asciidoctor --info + rm -rf "$WORKDIR/html5/content" && mkdir "$WORKDIR/html5/content" && mv -f "$WORKDIR/html5/"*.html "$WORKDIR/html5/content" + mv -f "$WORKDIR/html5/content/overview.html" "$WORKDIR/html5/content/index.html" +elif [ "$OUTPUT_FORMAT" = "markdown" ] ; +then + # Generate TOC for definitions & operations as README.md + cd "$WORKDIR" + echo "# KubeVirt API Reference" > README.md + curl \ + https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc | \ + bash -s "definitions.md" "operations.md" | \ + sed 's/^ //' >> "README.md" + cd - +fi + +echo "SUCCESS" diff --git a/hack/gen-swagger-doc/gradle.properties b/hack/gen-swagger-doc/gradle.properties new file mode 100644 index 000000000000..284894e36d1a --- /dev/null +++ b/hack/gen-swagger-doc/gradle.properties @@ -0,0 +1 @@ +markupLanguage=ASCIIDOC