hugo/content/en/contribute/development.md
Bjørn Erik Pedersen 87de22d746 Squashed 'docs/' changes from 85befbb4d..c43daf45f
c43daf45f Update build-options.md
3ebbfedd4 Build options: Improve readability
5091bf6a0 Improve safeHTMLAttr explanation
b64cbce2e Fix description of collections.Apply
6ea264b9c netlify: Hugo 0.115.4
b42e7c542 Revert "config: Remove disableLiveReload"
35ce2290e Remove excess spaces in configuration docs
2edf761de Update listed titleCaseStyle default value
887f6fb97 config: Remove disableLiveReload
c9f49fb26 Fix typo
37d8569ac Remove tools associated with Atom
871d11b72 Fix URL in postprocess docs
bbb17d29f Update GitLab workflow
bc53ea5ce Use sentence-style capitalization for headings
7ca578786 netlify: Hugo 0.115.3
c5e010bd0 Merge branch 'tempv0.115.3'
c885604bf Remove starter kits page
4c0fe269e Update mention of Netlify CMS to Decap CMS
05067175c Consistently use file name instead of filename
763dd6404 Improve multilingual config example and descriptions
e5aa61ec5 Use lowercase when referring to front matter (#2132)
7ba3d0c72 docs: Refresh docs.json
de8bddedf Update description of timeout configuration value
e1245d9f8 netify: Hugo 0.115.2
153a36bdf Merge branch 'tempv0.115.2'
707cec754 Fix typo in figure example in shortcodes.md
128cbe1e5 Improve taxonomy template examples
4e743ec36 Improve highlight function example
f96fa6805 transpile sass: Fixes typo
e4a8a21f7 Compile Sass to CSS, not SCSS
c1538bd00 docs: Regenerate CLI docs
bd4e33436 Add titleCaseStyle none and firstupper
6ff93d478 Update quick-start.md
5c6653cb1 Update build config examples and explanation
1458d9a43 Remove the `url` parameter
6a1e92044 netlify: Hugo 0.115.1
a9d5d6f2f Merge branch 'tempv0.115.1'
4c4882384 docs: Regen docs helper
d1aa1c1f5 Add link to PowerShell vs Windows PowerShell documentation
6e3b70c21 Fix link to Git installation instructions
4f8a9ca38 Clarify resources.Copy arguments
ee86dd121 Update theme
dc7c305cf Update theme
60c23920b Clarify caching for resources.FromString (#2120)
5bf2fef6d netlify: Hugo 0.115.0
46bde87c5 Merge branch 'tempv0.115.0'
42cc48c16 Specify target path caching for resources.ExecuteAsTemplate (#2027)
a54bf4cd0 Correct the sample code of mermaid (#2119)
8c49b06fc docs: Update permalinks documentation
a4818d99b Page bundles: link to info about single vs. list page templates (#2116)
3fc7744d7 snap: Document removable media access
dbd08f58a Update theme
df5b88633 netlify: Hugo 0.114.1
6b859834a Fix typo
9ec92cf68 Improve Dart Sass example for Netlify
2d294ece9 Add Dart Sass installation and usage documentation
4c6b77d6c Fix placement of curly braces
897812a50 Update template-debugging.md to include a jsonify example
22bca519b Update GitHub Pages hosting instructions (#2109)
a964d93ce Document math functions new in v0.114.0 (#2108)
9f4cb040e netlify: Hugo 0.114.0
55b4d9221 Merge branch 'tempv0.114.0'
93c4dcf93 docs: Regen docshelper
96f03c77f docs: Regen CLI docs
8e22a228a Clarify resource media type variables (#2106)
2652da8d4 Update transform.Unmarshal.md (#2105)
92657177a Update theme
4601c1d65 Update theme
a216f3145 Merge commit '3c1deaf201a35de08d23cc58f8f03682cace3349'
eed8794f5 cache: Set default cache path based on $USER

git-subtree-dir: docs
git-subtree-split: c43daf45fdc36c254f4274a0815ea62d4d8c37e0
2023-07-29 11:15:54 +02:00

18 KiB

title linkTitle description categories keywords menu weight toc
Contribute to development Development Hugo relies heavily on contributions from the open source community.
contribute
dev
open source
docs
parent weight
contribute 20
20 true

Introduction

Hugo is an open-source project and lives by the work of its contributors. There are plenty of open issues, and we need your help to make Hugo even more awesome. You don't need to be a Go guru to contribute to the project's development.

Assumptions

This contribution guide takes a step-by-step approach in hopes of helping newcomers. Therefore, we only assume the following:

  • You are new to Git or open-source projects in general
  • You are a fan of Hugo and enthusiastic about contributing to the project

{{% note %}} If you're struggling at any point in this contribution guide, reach out to the Hugo community in Hugo's Discussion forum. {{% /note %}}

Install Go

The installation of Go should take only a few minutes. You have more than one option to get Go up and running on your machine.

If you are having trouble following the installation guides for Go, check out Go Bootcamp, which contains setups for every platform or reach out to the Hugo community in the Hugo Discussion Forums.

Install Go from source

Download the latest stable version of Go and follow the official Go installation guide.

Once you're finished installing Go, let's confirm everything is working correctly. Open a terminal---or command line under Windows--and type the following:

go version

You should see something similar to the following written to the console. Note that the version here reflects the most recent version of Go as of the last update for this page:

go version go1.12 darwin/amd64

Next, make sure that you set up your GOPATH as described in the installation guide.

You can print the GOPATH with echo $GOPATH. You should see a non-empty string containing a valid path to your Go workspace; for example:

/Users/<yourusername>/Code/go

Install Go with Homebrew

If you are a macOS user and have Homebrew installed on your machine, installing Go is as simple as the following command:

{{< code file="install-go.sh" >}} brew install go {{< /code >}}

Install Go via GVM

More experienced users can use the Go Version Manager (GVM). GVM allows you to switch between different Go versions on the same machine. If you're a beginner, you probably don't need this feature. However, GVM makes it easy to upgrade to a new released Go version with just a few commands.

GVM comes in especially handy if you follow the development of Hugo over a longer period of time. Future versions of Hugo will usually be compiled with the latest version of Go. Sooner or later, you will have to upgrade if you want to keep up.

Create a GitHub account

If you're going to contribute code, you'll need to have an account on GitHub. Go to www.github.com/join and set up a personal account.

Install Git on your system

You will need to have Git installed on your computer to contribute to Hugo development. Teaching Git is outside the scope of the Hugo docs, but if you're looking for an excellent reference to learn the basics of Git, we recommend the Git book if you are not sure where to begin. We will include short explanations of the Git commands in this document.

Git is a version control system to track the changes of source code. Hugo depends on smaller third-party packages that are used to extend the functionality. We use them because we don't want to reinvent the wheel.

Go ships with a sub-command called get that will download these packages for us when we set up our working environment. The source code of the packages is tracked with Git. get will interact with the Git servers of the package hosters in order to fetch all dependencies.

Move back to the terminal and check if Git is already installed. Type in git version and press enter. You can skip the rest of this section if the command returned a version number. Otherwise download the latest version of Git and follow this installation guide.

Finally, check again with git version if Git was installed successfully.

Git graphical front ends

There are several GUI clients that help you to operate Git. Not all are available for all operating systems and maybe differ in their usage. Because of this we will document how to use the command-line, since the commands are the same everywhere.

Install Hub on your system (optional)

Hub is a great tool for working with GitHub. The main site for it is hub.github.com. Feel free to install this little Git wrapper.

On a Mac, you can install Hub using Homebrew:

brew install hub

Now we'll create an alias in Bash so that typing git actually runs Hub:

echo "alias git='hub'" >> ~/.bash_profile

Confirm the installation:

git version 2.21.0
hub version 2.10.0

Set up your working copy

You set up the working copy of the repository locally on your computer. Your local copy of the files is what you'll edit, compile, and end up pushing back to GitHub. The main steps are cloning the repository and creating your fork as a remote.

Clone the repository

We assume that you've set up your GOPATH (see the section above if you're unsure about this). You should now copy the Hugo repository down to your computer. You'll hear this called "clone the repo". GitHub's help pages give us a short explanation:

{{% note %}} When you create a repository on GitHub, it exists as a remote repository. You can create a local clone of your repository on your computer and sync between the two locations. {{% /note %}}

We're going to clone the master Hugo repository. That seems counter-intuitive, since you won't have commit rights on it. But it's required for the Go workflow. You'll work on a copy of the master and push your changes to your own repository on GitHub.

So, let's make a new directory and clone that master repository:

mkdir $HOME/src
cd $HOME/src
git clone https://github.com/gohugoio/hugo.git

Since Hugo 0.48, Hugo uses the Go Modules support built into Go 1.11 to build. The easiest is to clone Hugo in a directory outside of GOPATH

And then, install dependencies of Hugo by running the following in the cloned directory:

cd $HOME/src/hugo
go install

Hugo relies on mage for some convenient build and test targets. If you don't already have it, get it:

go install github.com/magefile/mage@latest

Fork the repository

If you're not familiar with this term, GitHub's help pages provide again a simple explanation:

{{% note %}} A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project. {{% /note %}}

Fork by hand

Open the Hugo repository on GitHub and click on the "Fork" button in the top right.

Fork button

Now open your fork repository on GitHub and copy the remote URL of your fork. You can choose between HTTPS and SSH as protocol that Git should use for the following operations. HTTPS works always if you're not sure.

Copy remote url

Switch back to the terminal and move into the directory of the cloned master repository from the last step.

cd $HOME/src/hugo

Now Git needs to know that our fork exists by adding the copied remote url:

git remote add <YOUR-GITHUB-USERNAME> <COPIED REMOTE-URL>

Fork with Hub

Alternatively, you can use the Git wrapper Hub. Hub makes forking a repository easy:

git fork

That command will log in to GitHub using your account, create a fork of the repository that you're currently working in, and add it as a remote to your working copy.

Trust, but verify

Let's check if everything went right by listing all known remotes:

git remote -v

The output should look similar:

digitalcraftsman    git@github.com:digitalcraftsman/hugo.git (fetch)
digitalcraftsman    git@github.com:digitalcraftsman/hugo.git (push)
origin  https://github.com/gohugoio/hugo (fetch)
origin  https://github.com/gohugoio/hugo (push)

The Hugo Git contribution workflow

Create a new branch

You should never develop against the "master" branch. The development team will not accept a pull request against that branch. Instead, create a descriptive named branch and work on it.

First, you should always pull the latest changes from the master repository:

git checkout master
git pull

Now we can create a new branch for your additions:

git checkout -b <BRANCH-NAME>

You can check on which branch you are with git branch. You should see a list of all local branches. The current branch is indicated with a little asterisk.

Contribute to documentation

Perhaps you want to start contributing to the Hugo docs. If so, you can ignore most of the following steps and focus on the /docs directory within your newly cloned repository. You can change directories into the Hugo docs using cd docs.

You can start Hugo's built-in server via hugo server. Browse the documentation by entering http://localhost:1313 in the address bar of your browser. The server automatically updates the page whenever you change content.

We have developed a separate Hugo documentation contribution guide for more information on how the Hugo docs are built, organized, and improved by the generosity of people like you.

Build Hugo

While making changes in the codebase it's a good idea to build the binary to test them:

mage hugo

This command generates the binary file at the root of the repository.

If you want to install the binary in $GOPATH/bin, run

mage install

Test

Sometimes changes on the codebase can cause unintended side effects. Or they don't work as expected. Most functions have their own test cases. You can find them in files ending with _test.go.

Make sure the commands

mage -v check

passes.

Formatting

The Go code style guide maybe is opinionated but it ensures that the codebase looks the same, regardless who wrote the code. Go comes with its own formatting tool. Let's apply the style guide to our additions:

mage fmt

Once you made your additions commit your changes. Make sure that you follow our code contribution guidelines:

# Add all changed files
git add --all
git commit --message "YOUR COMMIT MESSAGE"

The commit message should describe what the commit does (e.g. add feature XYZ), not how it is done.

Modify commits

You noticed some commit messages don't fulfill the code contribution guidelines or you just forget something to add some files? No problem. Git provides the necessary tools to fix such problems. The next two methods cover all common cases.

If you are unsure what a command does leave the commit as it is. We can fix your commits later in the pull request.

Modify the last commit

Let's say you want to modify the last commit message. Run the following command and replace the current message:

git commit --amend -m"YOUR NEW COMMIT MESSAGE"

Take a look at the commit log to see the change:

git log
# Exit with q

After making the last commit you may have forgotten something. There is no need to create a new commit. Just add the latest changes and merge them into the intended commit:

git add --all
git commit --amend

Modify multiple commits

{{% warning "Be Careful Modifying Multiple Commits"%}} Modifications such as those described in this section can have serious unintended consequences. Skip this section if you're not sure! {{% /note %}}

This is a bit more advanced. Git allows you to rebase commits interactively. In other words: it allows you to rewrite the commit history.

git rebase --interactive @~6

The 6 at the end of the command represents the number of commits that should be modified. An editor should open and present a list of last six commit messages:

pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
pick aaee038 tpl: Sort the smoke tests
pick f0dbf2c tpl: Add the other test case for hasPrefix
pick 911c35b Add "How to contribute to Hugo" tutorial
pick 33c8973 Begin workflow
pick 3502f2e Refactoring and typo fixes

In the case above we should merge the last two commits in the commit of this tutorial (Add "How to contribute to Hugo" tutorial). You can "squash" commits, i.e. merge two or more commits into a single one.

All operations are written before the commit message. Replace "pick" with an operation. In this case squash or s for short:

pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
pick aaee038 tpl: Sort the smoke tests
pick f0dbf2c tpl: Add the other test case for hasPrefix
pick 911c35b Add "How to contribute to Hugo" tutorial
squash 33c8973 Begin workflow
squash 3502f2e Refactoring and typo fixes

We also want to rewrite the commits message of the third last commit. We forgot "docs:" as prefix according to the code contribution guidelines. The operation to rewrite a commit is called reword (or r as shortcut).

You should end up with a similar setup:

pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
pick aaee038 tpl: Sort the smoke tests
pick f0dbf2c tpl: Add the other test case for hasPrefix
reword 911c35b Add "How to contribute to Hugo" tutorial
squash 33c8973 Begin workflow
squash 3502f2e Refactoring and typo fixes

Close the editor. It should open again with a new tab. A text is instructing you to define a new commit message for the last two commits that should be merged (aka "squashed"). Save the file with CTRL+S and close the editor again.

A last time a new tab opens. Enter a new commit message and save again. Your terminal should contain a status message. Hopefully this one:

Successfully rebased and updated refs/heads/<BRANCHNAME>.

Check the commit log if everything looks as expected. Should an error occur you can abort this rebase with git rebase --abort.

Push commits

To push our commits to the fork on GitHub we need to specify a destination. A destination is defined by the remote and a branch name. Earlier, the defined that the remote URL of our fork is the same as our GitHub handle, in my case digitalcraftsman. The branch should have the same as our local one. This makes it easy to identify corresponding branches.

git push --set-upstream <YOUR-GITHUB-USERNAME> <BRANCHNAME>

Now Git knows the destination. Next time when you to push commits you just need to enter git push.

If you modified your commit history in the last step GitHub will reject your try to push. This is a safety-feature because the commit history isn't the same and new commits can't be appended as usual. You can enforce this push explicitly with git push --force.

Open a pull request

We made a lot of progress. Good work. In this step we finally open a pull request to submit our additions. Open the Hugo master repository on GitHub in your browser.

You should find a green button labeled with "New pull request". But GitHub is clever and probably suggests you a pull request like in the beige box below:

Open a pull request

The new page summaries the most important information of your pull request. Scroll down and you find the additions of all your commits. Make sure everything looks as expected and click on "Create pull request".

Accept the contributor license agreement

Last but not least you should accept the contributor license agreement (CLA). A new comment should be added automatically to your pull request. Click on the yellow badge, accept the agreement and authenticate yourself with your GitHub account. It just takes a few clicks and only needs to be done once.

Accept the CLA

Automatic builds

We use a GitHub Actions workflow to build and test. This is a matrix build across combinations of operating system (macOS, Windows, and Ubuntu) and Go versions. The workflow is triggered by the submission of a pull request. If you are a first-time contributor, the workflow requires approval from a project maintainer.

Where to start?

Thank you for reading through this contribution guide. Hopefully, we will see you again soon on GitHub. There are plenty of open issues for you to help with.

Feel free to open an issue if you think you found a bug or you have a new idea to improve Hugo. We are happy to hear from you.

Additional references for learning Git and Go