diff --git a/.drone.sh b/.drone.sh new file mode 100755 index 0000000..dcde802 --- /dev/null +++ b/.drone.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +set -e +set -x + +# compile the main binary +GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/amd64/drone-hugo github.com/drone-plugins/drone-hugo/cmd/drone-hugo +GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/arm64/drone-hugo github.com/drone-plugins/drone-hugo/cmd/drone-hugo +GOOS=linux GOARCH=arm CGO_ENABLED=0 GOARM=7 go build -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/arm/drone-hugo github.com/drone-plugins/drone-hugo/cmd/drone-hugo +GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/i386/drone-hugo github.com/drone-plugins/drone-hugo/cmd/drone-hugo \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2aa6311 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/* +release +coverage.out +vendor diff --git a/docs/tmpl.md b/DOCS.md similarity index 64% rename from docs/tmpl.md rename to DOCS.md index f360828..52d857d 100644 --- a/docs/tmpl.md +++ b/DOCS.md @@ -1,6 +1,6 @@ -# drone-hugo +drone-hugo -[![GitHub release](https://img.shields.io/github/release/drone-plugins/drone-hugo.svg)](https://github.com/plugins/hugo/releases) ![](https://img.shields.io/badge/hugo%20version-v-ff69b4.svg) +[![GitHub release](https://img.shields.io/github/release/drone-plugins/drone-hugo.svg)](https://github.com/plugins/hugo/releases) ![](https://img.shields.io/badge/hugo%20version-v0.40.2-ff69b4.svg) [![Docker Pulls](https://img.shields.io/docker/pulls/plugins/hugo.svg)](https://hub.docker.com/r/plugins/hugo/tags/) **Automatically create static web page files using Hugo within your drone pipeline!** @@ -17,9 +17,9 @@ The example below demonstrates how you can use the plugin to automatically creat ```yml pipeline: - hugo: - image: plugins/hugo: - validate: true + hugo: + image: plugins/hugo:latest + validate: true ``` `validate` allows you to check your configuration file for errors before generating the files. @@ -30,15 +30,15 @@ You can customize the paths for e. g. the theme, layout, content directory and o ```yml pipeline: - hugo: - image: plugins/hugo: + hugo: + image: plugins/hugo:latest + config: path/to/config + content: path/to/content/ + layout: path/to/layout + output: path/to/public + source: path/to/source + theme: path/themes/THEMENAME/ - validate: true + validate: true ``` ### Set hostname (and path) to the root @@ -47,15 +47,15 @@ You can also define a base URL directly in the pipeline, which is used when gene ```yml pipeline: - hugo: - image: plugins/hugo: - config: path/to/config - content: path/to/content/ - output: path/to/public - source: path/to/source - theme: path/themes/THEMENAME/ + hugo: + image: plugins/hugo:latest + config: path/to/config + content: path/to/content/ + output: path/to/public + source: path/to/source + theme: path/themes/THEMENAME/ + url: https://example.com - validate: true + validate: true ``` ### Build sites and include expired, drafts or future content @@ -68,18 +68,18 @@ You can set the `buildDrafts`, `buildExpired`, `buildFuture` settings to configu ```yml pipeline: - hugo: - image: plugins/hugo: + hugo: + image: plugins/hugo:latest + buildDrafts: true + buildExpired: true + buildFuture: true - config: path/to/config - content: path/to/content/ - output: path/to/public - source: path/to/source - theme: path/themes/THEMENAME/ - url: https://example.com - validate: true + config: path/to/config + content: path/to/content/ + output: path/to/public + source: path/to/source + theme: path/themes/THEMENAME/ + url: https://example.com + validate: true ``` ### **Example**: Generate Hugo static files and publish them to remote directory using scp @@ -88,67 +88,67 @@ Here is a short example of how to define a pipeline that automatically generates ```yml pipeline: - build: - image: plugins/hugo: - output: site # Output path - validate: true - when: - branch: [ master ] - publish: - image: appleboy/drone-scp - host: example.com - username: webuser - password: xxxxxxx - port: 54321 - target: /var/www/ # Path to your web directory - source: site/* # Copy all files from output path + build: + image: plugins/hugo:latest + output: site # Output path + validate: true + when: + branch: [ master ] + publish: + image: appleboy/drone-scp + host: example.com + username: webuser + password: xxxxxxx + port: 54321 + target: /var/www/ # Path to your web directory + source: site/* # Copy all files from output path ``` You can also use secrets to hide credentials: ```yml pipeline: - build: - image: plugins/hugo: - output: site # Output path - validate: true - when: - branch: [ master ] - publish: - image: appleboy/drone-scp + build: + image: plugins/hugo:latest + output: site # Output path + validate: true + when: + branch: [ master ] + publish: + image: appleboy/drone-scp + secrets: [ ssh_username, ssh_password ] - host: example.com + host: example.com - username: webuser - password: xxxxxxx - port: 54321 - target: /var/www/ # Path to your web directory - source: site/* # Copy all files from output path + port: 54321 + target: /var/www/ # Path to your web directory + source: site/* # Copy all files from output path ``` ## Basic Usage using a Docker Container ```bash docker run --rm \ - -e PLUGIN_VERSION= \ - -e PLUGIN_BUILDDRAFTS=false \ - -e PLUGIN_BUILDEXPIRED=false \ - -e PLUGIN_BUILDFUTURE=false \ - -e PLUGIN_CONFIG=false \ - -e PLUGIN_CONTENT=false \ - -e PLUGIN_LAYOUT=false \ - -e PLUGIN_OUTPUT=false \ - -e PLUGIN_SOURCE=false \ - -e PLUGIN_THEME=false \ - -e PLUGIN_OUTPUT=false \ - -e PLUGIN_VALIDATE=false \ - -v $(pwd):$(pwd) \ - -w $(pwd) \ - plugins/hugo:latest + -e PLUGIN_VERSION=0.40.2 \ + -e PLUGIN_BUILDDRAFTS=false \ + -e PLUGIN_BUILDEXPIRED=false \ + -e PLUGIN_BUILDFUTURE=false \ + -e PLUGIN_CONFIG=false \ + -e PLUGIN_CONTENT=false \ + -e PLUGIN_LAYOUT=false \ + -e PLUGIN_OUTPUT=false \ + -e PLUGIN_SOURCE=false \ + -e PLUGIN_THEME=false \ + -e PLUGIN_OUTPUT=false \ + -e PLUGIN_VALIDATE=false \ + -v $(pwd):$(pwd) \ + -w $(pwd) \ + plugins/hugo:latest ``` ## Parameter Reference -`version` - the hugo version to be used, if not set use v. +`hugoVersion` - the hugo version to be used, if not set use v. `buildDrafts` - include content marked as draft
`buildExpired` - include expired content
`buildFuture` - include content with publishdate in the future
diff --git a/Dockerfile b/Dockerfile index 7ed2c3d..d448ea1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,22 @@ -FROM alpine:latest -LABEL maintainer="chris@cbrgm.de" -LABEL version="latest" +FROM plugins/base:amd64 + +LABEL maintainer="Drone.IO Community " \ + org.label-schema.name="Drone Hugo" \ + org.label-schema.vendor="Drone.IO Community" \ + org.label-schema.schema-version="1.0" ARG HUGO_VERSION +ARG HUGO_ARCH +ENV PLUGIN_HUGO_ARCH=$HUGO_ARCH +ENV PLUGIN_HUGO_SHIPPED_VERSION=$HUGO_VERSION -COPY ./drone-hugo.sh /bin/ - +ADD release/linux/amd64/drone-hugo /bin/ RUN apk update && \ apk --no-cache add git && \ - chmod +x bin/drone-hugo.sh && \ + chmod +x bin/drone-hugo && \ mkdir /temp/ && \ - wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz | tar xz -C /temp/ && \ + wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-${HUGO_ARCH}.tar.gz | tar xz -C /temp/ && \ mv /temp/hugo /bin/hugo && \ rm -rf /temp -ENTRYPOINT /bin/sh /bin/drone-hugo.sh +ENTRYPOINT ["/bin/drone-hugo"] diff --git a/Dockerfile.arm b/Dockerfile.arm new file mode 100644 index 0000000..7b12715 --- /dev/null +++ b/Dockerfile.arm @@ -0,0 +1,22 @@ +FROM plugins/base:arm + +LABEL maintainer="Drone.IO Community " \ + org.label-schema.name="Drone Hugo" \ + org.label-schema.vendor="Drone.IO Community" \ + org.label-schema.schema-version="1.0" + +ARG HUGO_VERSION +ARG HUGO_ARCH +ENV PLUGIN_HUGO_ARCH=$HUGO_ARCH +ENV PLUGIN_HUGO_SHIPPED_VERSION=$HUGO_VERSION + +ADD release/linux/arm/drone-hugo /bin/ +RUN apk update && \ + apk --no-cache add git && \ + chmod +x bin/drone-hugo && \ + mkdir /temp/ && \ + wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-${HUGO_ARCH}.tar.gz | tar xz -C /temp/ && \ + mv /temp/hugo /bin/hugo && \ + rm -rf /temp + +ENTRYPOINT ["/bin/drone-hugo"] diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 new file mode 100644 index 0000000..7998546 --- /dev/null +++ b/Dockerfile.arm64 @@ -0,0 +1,22 @@ +FROM plugins/base:arm64 + +LABEL maintainer="Drone.IO Community " \ + org.label-schema.name="Drone Hugo" \ + org.label-schema.vendor="Drone.IO Community" \ + org.label-schema.schema-version="1.0" + +ARG HUGO_VERSION +ARG HUGO_ARCH +ENV PLUGIN_HUGO_ARCH=$HUGO_ARCH +ENV PLUGIN_HUGO_SHIPPED_VERSION=$HUGO_VERSION + +ADD release/linux/arm64/drone-hugo /bin/ +RUN apk update && \ + apk --no-cache add git && \ + chmod +x bin/drone-hugo && \ + mkdir /temp/ && \ + wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-${HUGO_ARCH}.tar.gz | tar xz -C /temp/ && \ + mv /temp/hugo /bin/hugo && \ + rm -rf /temp + +ENTRYPOINT ["/bin/drone-hugo"] diff --git a/Dockerfile.i386 b/Dockerfile.i386 new file mode 100644 index 0000000..9677bd7 --- /dev/null +++ b/Dockerfile.i386 @@ -0,0 +1,22 @@ +FROM plugins/base:i386 + +LABEL maintainer="Drone.IO Community " \ + org.label-schema.name="Drone Hugo" \ + org.label-schema.vendor="Drone.IO Community" \ + org.label-schema.schema-version="1.0" + +ARG HUGO_VERSION +ARG HUGO_ARCH +ENV PLUGIN_HUGO_ARCH=$HUGO_ARCH +ENV PLUGIN_HUGO_SHIPPED_VERSION=$HUGO_VERSION + +ADD release/linux/i386/drone-hugo /bin/ +RUN apk update && \ + apk --no-cache add git && \ + chmod +x bin/drone-hugo && \ + mkdir /temp/ && \ + wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-${HUGO_ARCH}.tar.gz | tar xz -C /temp/ && \ + mv /temp/hugo /bin/hugo && \ + rm -rf /temp + +ENTRYPOINT ["/bin/drone-hugo"] diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..3b5fa83 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,21 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/urfave/cli" + packages = ["."] + revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" + version = "v1.20.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "28e40bf4884feea380a4b1053274ed222e42a29ac274a1f998fb48da777b1295" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..75047c4 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,34 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + name = "github.com/urfave/cli" + version = "1.20.0" + +[prune] + go-tests = true + unused-packages = true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index a612ad9..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/Makefile b/Makefile index 85da8cd..42c64e4 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,17 @@ -.PHONY: all test push build release clean +.PHONY: test build amd64 arm64 arm i386 -README_TEMPLATE=./docs/tmpl.md +test: + dep ensure + go test ./... -all: release +build: .drone.sh + ./.drone.sh -test: Dockerfile drone-hugo.sh - docker build -t "plugins/hugo:$(release)_test" --build-arg HUGO_VERSION="$(hugo)" . +amd64: Dockerfile + docker build -t "plugins/hugo:amd64" --build-arg HUGO_VERSION="$(hugo)" --build-arg HUGO_ARCH=64bit . -build: Dockerfile drone-hugo.sh - docker build -t "plugins/hugo:$(release)" --build-arg HUGO_VERSION="$(hugo)" . - docker build -t "plugins/hugo:latest" --build-arg HUGO_VERSION="$(hugo)" . +arm64: Dockerfile.arm64 + docker build -t "plugins/hugo:arm64" --build-arg HUGO_VERSION="$(hugo)" --build-arg HUGO_ARCH=arm64 . -push: build - docker push "plugins/hugo:$(release)" - docker push "plugins/hugo:latest" - -release: $(README_TEMPLATE) test push build clean - sed 's//$(hugo)/g' $(README_TEMPLATE) > temp.md - sed 's//$(release)/g' temp.md > README.md - rm -rf temp.md - git add . - git commit -m "Updated to the latest Hugo version v.$(hugo), see https://github.com/gohugoio/hugo/releases" - git push origin master - -clean: - docker rmi plugins/hugo:$(release) - docker rmi plugins/hugo:latest - docker rmi plugins/hugo:$(release)_test +arm: Dockerfile.arm + docker build -t "plugins/hugo:arm" --build-arg HUGO_VERSION="$(hugo)" --build-arg HUGO_ARCH=arm . \ No newline at end of file diff --git a/README.md b/README.md index 5662946..dac9ce8 100644 --- a/README.md +++ b/README.md @@ -1,135 +1,28 @@ # drone-hugo -[![GitHub release](https://img.shields.io/github/release/drone-plugins/drone-hugo.svg)](https://github.com/plugins/hugo/releases) ![](https://img.shields.io/badge/hugo%20version-v0.40.2-ff69b4.svg) -[![Docker Pulls](https://img.shields.io/docker/pulls/plugins/hugo.svg)](https://hub.docker.com/r/plugins/hugo/tags/) +Automatically create static web page files using [hugo](https://github.com/gohugoio/hugo) within your drone pipeline! -**Automatically create static web page files using Hugo within your drone pipeline!** +## Build -plugins/hugo is: +Build the binaries with the following commands: -- **Easy** to implement in your existing pipeline using `.drone.yml` -- **Small** 21mb image size -- **Highly configurable** - -## Basic Usage with Drone CI - -The example below demonstrates how you can use the plugin to automatically create static web page files using Hugo. **It's as easy as pie!** - -```yml -pipeline: - hugo: - image: plugins/hugo:1.1 - validate: true +```go +make build ``` -`validate` allows you to check your configuration file for errors before generating the files. +## Docker -### Customize source, output, theme, config, layout OR content directory paths +Build the Docker image with the following commands: -You can customize the paths for e. g. the theme, layout, content directory and output directory and much more! - -```yml -pipeline: - hugo: - image: plugins/hugo:1.1 -+ config: path/to/config -+ content: path/to/content/ -+ layout: path/to/layout -+ output: path/to/public -+ source: path/to/source -+ theme: path/themes/THEMENAME/ - validate: true +```bash +make [amd64,arm64,amd] hugo=0.00.0 ``` -### Set hostname (and path) to the root - -You can also define a base URL directly in the pipeline, which is used when generating the files. - -```yml -pipeline: - hugo: - image: plugins/hugo:1.1 - config: path/to/config - content: path/to/content/ - output: path/to/public - source: path/to/source - theme: path/themes/THEMENAME/ -+ url: https://example.com - validate: true -``` - -### Build sites and include expired, drafts or future content - -You can set the `buildDrafts`, `buildExpired`, `buildFuture` settings to configure the generated files. - -- `buildDrafts` - include content marked as draft -- `buildExpired` - include expired content -- `buildFuture` - include content with publishdate in the future - -```yml -pipeline: - hugo: - image: plugins/hugo:1.1 -+ buildDrafts: true -+ buildExpired: true -+ buildFuture: true - config: path/to/config - content: path/to/content/ - output: path/to/public - source: path/to/source - theme: path/themes/THEMENAME/ - url: https://example.com - validate: true -``` - -### **Example**: Generate Hugo static files and publish them to remote directory using scp - -Here is a short example of how to define a pipeline that automatically generates the static web page files with Hugo and then copies them to a remote server via scp. This makes publishing websites a breeze! - -```yml -pipeline: - build: - image: plugins/hugo:1.1 - output: site # Output path - validate: true - when: - branch: [ master ] - publish: - image: appleboy/drone-scp - host: example.com - username: webuser - password: xxxxxxx - port: 54321 - target: /var/www/ # Path to your web directory - source: site/* # Copy all files from output path -``` - -You can also use secrets to hide credentials: - -```yml -pipeline: - build: - image: plugins/hugo:1.1 - output: site # Output path - validate: true - when: - branch: [ master ] - publish: - image: appleboy/drone-scp -+ secrets: [ ssh_username, ssh_password ] - host: example.com -- username: webuser -- password: xxxxxxx - port: 54321 - target: /var/www/ # Path to your web directory - source: site/* # Copy all files from output path -``` - -## Basic Usage using a Docker Container +### Usage ```bash docker run --rm \ - -e PLUGIN_VERSION=0.40.2 \ + -e PLUGIN_HUGO_VERSION=0.00.0 \ -e PLUGIN_BUILDDRAFTS=false \ -e PLUGIN_BUILDEXPIRED=false \ -e PLUGIN_BUILDFUTURE=false \ @@ -145,24 +38,3 @@ docker run --rm \ -w $(pwd) \ plugins/hugo:latest ``` - -## Parameter Reference - -`version` - the hugo version to be used, if not set use v.0.40.2 -`buildDrafts` - include content marked as draft
-`buildExpired` - include expired content
-`buildFuture` - include content with publishdate in the future
-`config` - config file (default is path/config.yaml|json|toml)
-`content` - filesystem path to content directory
-`layout` - filesystem path to layout directory
-`output` - filesystem path to write files to
-`source` - filesystem path to read files relative from
-`theme` - theme to use (located in /themes/THEMENAME/)
-`url` - hostname (and path) to the root
-`validate` - validate config file before generation - -## Contributing - -You have suggestions for improvements or features you miss? You are welcome to express all your wishes here. Just create a new Issue and it will be taken care of quickly! - -If you are a developer yourself, you can also contribute code! Further information will follow shortly. diff --git a/cmd/drone-hugo/main.go b/cmd/drone-hugo/main.go new file mode 100644 index 0000000..913917f --- /dev/null +++ b/cmd/drone-hugo/main.go @@ -0,0 +1,116 @@ +package main + +import ( + "fmt" + "log" + "os" + + "github.com/drone-plugins/drone-hugo" + "github.com/urfave/cli" +) + +var build = "0" // build number set at compile-time +var version = "2.0" + +func main() { + app := cli.NewApp() + app.Name = "hugo plugin" + app.Usage = "hugo plugin" + app.Action = run + app.Version = fmt.Sprintf("%s build %s", version, build) + app.Flags = []cli.Flag{ + cli.BoolFlag{ + Name: "buildDrafts", + Usage: " include content marked as draft", + EnvVar: "PLUGIN_BUILDDRAFTS", + }, + cli.BoolFlag{ + Name: "buildExpired", + Usage: "include expired content", + EnvVar: "PLUGIN_BUILDEXPIRED", + }, + cli.BoolFlag{ + Name: "buildFuture", + Usage: "include content with publishdate in the future", + EnvVar: "PLUGIN_BUILDFUTURE", + }, + cli.StringFlag{ + Name: "config", + Usage: "config file (default is path/config.yaml|json|toml)", + EnvVar: "PLUGIN_CONFIG", + Value: "", + }, + cli.StringFlag{ + Name: "content", + Usage: "filesystem path to content directory", + EnvVar: "PLUGIN_CONTENT", + Value: "", + }, + cli.StringFlag{ + Name: "layout", + Usage: "filesystem path to layout directory", + EnvVar: "PLUGIN_LAYOUT", + Value: "", + }, + cli.StringFlag{ + Name: "output", + Usage: "filesystem path to write files to", + EnvVar: "PLUGIN_OUTPUT", + Value: "", + }, + cli.StringFlag{ + Name: "source", + Usage: "filesystem path to read files relative from", + EnvVar: "PLUGIN_SOURCE", + Value: "", + }, + cli.StringFlag{ + Name: "theme", + Usage: "theme to use (located in /themes/THEMENAME/)", + EnvVar: "PLUGIN_THEME", + Value: "", + }, + cli.StringFlag{ + Name: "url", + Usage: "hostname (and path) to the root", + EnvVar: "PLUGIN_URL", + Value: "", + }, + cli.BoolFlag{ + Name: "validate", + Usage: "validate config file before generation", + EnvVar: "PLUGIN_VALIDATE", + }, + cli.StringFlag{ + Name: "hugoVersion", + Usage: "the hugo version to be used", + EnvVar: "PLUGIN_HUGO_VERSION", + Value: "", + }, + } + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +} + +func run(c *cli.Context) error { + plugin := hugo.Plugin{ + Config: hugo.Config{ + HugoVersion: c.String("hugoVersion"), + BuildDrafts: c.Bool("buildDrafts"), + BuildExpired: c.Bool("buildExpired"), + BuildFuture: c.Bool("buildFuture"), + Validate: c.Bool("validate"), + Config: c.String("config"), + Content: c.String("content"), + Layout: c.String("layout"), + Output: c.String("output"), + Source: c.String("source"), + Theme: c.String("theme"), + Url: c.String("url"), + }, + Architecture: os.Getenv("PLUGIN_HUGO_ARCH"), + BuildInVersion: os.Getenv("PLUGIN_HUGO_SHIPPED_VERSION"), + } + return plugin.Exec() +} diff --git a/download/download.go b/download/download.go new file mode 100644 index 0000000..dd5d5d2 --- /dev/null +++ b/download/download.go @@ -0,0 +1,73 @@ +package download + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "strings" + + "github.com/pkg/errors" + "log" + "net/http" +) + +var ( + _downloadURL = "https://github.com/gohugoio/hugo/releases/download/v%s/hugo_%s_Linux-%s.tar.gz" +) + +func downloadURL(version string, archType string) string { + return fmt.Sprintf(_downloadURL, version, version, archType) +} + +func getTempFile() (string, io.WriteCloser, error) { + d, err := ioutil.TempDir("", "") + if err != nil { + return "", nil, errors.Wrap(err, "") + } + f, err := ioutil.TempFile(d, "") + return f.Name(), f, err +} + +// Get will download the specified hugo verion +func Get(ver string, archType string) (string, error) { + resp, err := http.Get(downloadURL(ver, archType)) + if err != nil { + return "", errors.Wrap(err, "") + } + defer resp.Body.Close() + gz, err := gzip.NewReader(resp.Body) + if err != nil { + return "", errors.Wrap(err, "") + } + defer gz.Close() + targz := tar.NewReader(gz) + + hugoPath, hugoBin, err := getTempFile() + if err != nil { + log.Printf("ERROR: %s", err) + return "", errors.Wrap(err, "") + } + defer hugoBin.Close() + + for { + h, err := targz.Next() + if err == io.EOF { + return "", errors.New("no hugo binary found") + } + if err != nil { + return "", errors.Wrap(err, "") + } + if strings.HasSuffix(h.Name, "hugo") { + io.Copy(hugoBin, targz) + + if err := os.Chmod(hugoPath, 0755); err != nil { + log.Fatal(err) + } + + return hugoPath, nil + } + } +} diff --git a/download/download_test.go b/download/download_test.go new file mode 100644 index 0000000..6f66040 --- /dev/null +++ b/download/download_test.go @@ -0,0 +1,21 @@ +package download + +import ( + "testing" +) + +func TestDownloadURL(t *testing.T) { + want := "https://github.com/gohugoio/hugo/releases/download/v1.0/hugo_1.0_Linux-64bit.tar.gz" + if got := downloadURL("1.0", "64bit"); got != want { + t.Errorf("Download url is not correct, got: %s, want: %s", got, want) + } +} + +func TestGet(t *testing.T) { + if binPath , err := Get("0.42","64bit"); err != nil { + t.Errorf("Failed to download archive: %s", err) + if binPath == "" { + t.Errorf("binPath was nil") + } + } +} diff --git a/drone-hugo.sh b/drone-hugo.sh deleted file mode 100755 index d45300c..0000000 --- a/drone-hugo.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# Author: Christian Bargmann -set -e - -# Assign default variables if not set -PLUGIN_VERSION=${PLUGIN_VERSION:-"false"} -PLUGIN_BUILDDRAFTS=${PLUGIN_BUILDDRAFTS:-"false"} -PLUGIN_BUILDEXPIRED=${PLUGIN_BUILDEXPIRED:-"false"} -PLUGIN_BUILDFUTURE=${PLUGIN_BUILDFUTURE:-"false"} -PLUGIN_CONFIG=${PLUGIN_CONFIG:-"false"} -PLUGIN_CONTENT=${PLUGIN_CONTENT:-"false"} -PLUGIN_LAYOUT=${PLUGIN_LAYOUT:-"false"} -PLUGIN_OUTPUT=${PLUGIN_OUTPUT:-"false"} -PLUGIN_SOURCE=${PLUGIN_SOURCE:-"false"} -PLUGIN_THEME=${PLUGIN_THEME:-"false"} -PLUGIN_URL=${PLUGIN_URL:-"false"} -PLUGIN_VALIDATE=${PLUGIN_VALIDATE:-"false"} - -# The hugo command -HUGO_COMMAND="hugo" - -function addArgument { - echo $1 - HUGO_COMMAND="${HUGO_COMMAND} $1" -} - -# Download hugo binary if version attribute is set. When not set, use the one shipped binary inside container -if [[ $PLUGIN_VERSION != "false" ]] ; then - echo "Downloading hugo version v${PLUGIN_VERSION}..." - mkdir /temp/ - wget -qO- https://github.com/gohugoio/hugo/releases/download/v${PLUGIN_VERSION}/hugo_${PLUGIN_VERSION}_Linux-64bit.tar.gz | tar xz -C /temp/ - mv /temp/hugo /bin/hugo - rm -rf /temp - echo "Using hugo v${PLUGIN_VERSION}..." -fi - -# Validate config file -if [[ $PLUGIN_VALIDATE = true ]]; then - if [[ $PLUGIN_CONFIG != "false" ]]; then - echo "Checking config file ${PLUGIN_CONFIG}..." - hugo check --config ${PLUGIN_CONFIG} - else - hugo check - fi -fi - -# Create hugo command from arguments -if [[ $PLUGIN_BUILDDRAFTS != "false" ]] ; then addArgument "-D" ; fi -if [[ $PLUGIN_BUILDEXPIRED != "false" ]] ; then addArgument "-E" ; fi -if [[ $PLUGIN_BUILDFUTURE != "false" ]] ; then addArgument "-F" ; fi -if [[ $PLUGIN_CONFIG != "false" ]] ; then addArgument "--config ${PLUGIN_CONFIG}" ; fi -if [[ $PLUGIN_CONTENT != "false" ]] ; then addArgument "--contentDir ${PLUGIN_CONFIG}" ; fi -if [[ $PLUGIN_LAYOUT != "false" ]] ; then addArgument "--layoutDir ${PLUGIN_LAYOUT}" ; fi -if [[ $PLUGIN_OUTPUT != "false" ]] ; then addArgument "--destination ${PLUGIN_OUTPUT}" ; fi -if [[ $PLUGIN_SOURCE != "false" ]] ; then addArgument "--source ${PLUGIN_SOURCE}" ; fi -if [[ $PLUGIN_THEME != "false" ]] ; then addArgument "--theme ${PLUGIN_THEME}" ; fi -if [[ $PLUGIN_URL != "false" ]] ; then addArgument "--baseURL ${PLUGIN_URL}" ; fi - -echo "Executing: ${HUGO_COMMAND}" -$HUGO_COMMAND diff --git a/plugin.go b/plugin.go new file mode 100644 index 0000000..b1a15f0 --- /dev/null +++ b/plugin.go @@ -0,0 +1,131 @@ +package hugo + +import ( + "fmt" + "github.com/drone-plugins/drone-hugo/download" + "os" + "os/exec" + "strings" +) + +type ( + Plugin struct { + Config Config + Architecture string + BuildInVersion string + } + + Config struct { + BuildDrafts bool + BuildExpired bool + BuildFuture bool + Config string + Content string + Layout string + Output string + Source string + Theme string + Url string + HugoVersion string + Validate bool + } +) + +var hugoExecutable = "hugo" + +// Exec executes the plugins functionality +func (p Plugin) Exec() error { + var cmds = make([]*exec.Cmd, 0) + + // Check if buildIn plugin version equals + // plugin version declared in drone.yml + if !versionsEqual(p.BuildInVersion, p.Config.HugoVersion) { + hugoPath, err := download.Get(p.Config.HugoVersion, p.Architecture) + if err != nil { + return err + } + hugoExecutable = hugoPath + } + if p.Config.Validate { + cmds = append(cmds, commandValidate(p.Config)) + } + + cmds = append(cmds, commandBuild(p.Config)) + return execAll(cmds) +} + +func commandValidate(config Config) *exec.Cmd { + args := []string{"check"} + if config.Config != "" { + args = append(args, "--config", config.Config) + } + return exec.Command(hugoExecutable, args...) +} + +func commandBuild(config Config) *exec.Cmd { + var args = make([]string, 0) + + // add bool args + if config.BuildDrafts { + args = append(args, "-D") + } + if config.BuildExpired { + args = append(args, "-E") + } + if config.BuildFuture { + args = append(args, "-F") + } + // add string args + if config.Config != "" { + args = append(args, "--config", config.Config) + } + if config.Content != "" { + args = append(args, "--contentDir", config.Content) + } + if config.Layout != "" { + args = append(args, "--layoutDir", config.Layout) + } + if config.Output != "" { + args = append(args, "--destination", config.Output) + } + if config.Source != "" { + args = append(args, "--source", config.Source) + } + if config.Theme != "" { + args = append(args, "--theme", config.Theme) + } + if config.Url != "" { + args = append(args, "--baseURL", config.Url) + } + + return exec.Command(hugoExecutable, args...) +} + +// trace writes each command to stdout with the command wrapped in an xml +// tag so that it can be extracted and displayed in the logs. +func trace(cmd *exec.Cmd) { + fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " ")) +} + +func versionsEqual(version string, toCompare string) bool { + if toCompare == version || toCompare == "" { + return true + } else { + return false + } +} + +// execAll executes a slice of commands as a batch job +func execAll(cmds []*exec.Cmd) error { + // Execute all commands + for _, cmd := range cmds { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + trace(cmd) + + if err := cmd.Run(); err != nil { + return err + } + } + return nil +} diff --git a/plugin_test.go b/plugin_test.go new file mode 100644 index 0000000..29b716b --- /dev/null +++ b/plugin_test.go @@ -0,0 +1,45 @@ +package hugo + +import ( + "github.com/pkg/errors" + "testing" +) + +func TestCommandValidate(t *testing.T) { + config := Config{Validate: true} + want := []string{"hugo", "check"} + got := commandValidate(config) + + if err := argsEqual(want, got.Args); err != nil { + t.Errorf("%s", err) + } + + config = Config{Validate: true, Config: "config.toml"} + want = []string{"hugo", "check", "--config", "config.toml"} + got = commandValidate(config) + + if err := argsEqual(want, got.Args); err != nil { + t.Errorf("%s", err) + } +} + +func TestVersionEqual(t *testing.T) { + want := true + if got := versionsEqual("1.0", "1.0"); want != got { + t.Errorf("want: %t, got: %t", want, got) + } + + want = false + if got := versionsEqual("1.5", "1.0"); want != got { + t.Errorf("want: %t, got: %t", want, got) + } +} + +func argsEqual(want []string, got []string) error { + for i := range want { + if want[i] != got[i] { + return errors.Errorf("Arguments do not match, want: %s, got: %s", want[i], got[i]) + } + } + return nil +}