Go Quickstart
In this quick start guide, we will write our first script in Go.
Scripts are the basic building blocks in Windmill. They can be run as standalone apps, chained together to create Flows.
In Windmill, Scripts consist of three parts:
- Metadata: information about the Script such as its path, description, and author, as well as configuration.
- Logic: the code.
- UI: a UI autogenerated from the script signature, that can be customized.
For more information about how Scripts and Flows are represented within Windmill, also see the OpenFlow Spec.
In this quick start guide, we'll create a Script that greets the operator running it. From the Home page, click "+Script". This will take you to the first step of script creation: metadata.
Metadata
- Path is the Script's unique identifier that consist of the
script's owner, and the script's name.
The owner can be either a user, or a group (folder). This defines the permissions on
Windmill: selecting user will keep the script private to the selected
account, while selecting group will make it available to all users of the
given group. Let's save this script under your path, and call it
hello_world_go
. - Summary (optional) is a short, human-readable summary of the Script. It
will be displayed across Windmill. If omitted, the UI will use the
path
by default. Let's use "Greet the user by name". - Language the language of the script. Windmill supports TypeScript, Python, Go, Bash and SQL. Let's pick Go!
- Advanced gives you access to more options, such as creating specialized scripts and saving the script as a template. We won't go into this in this quickstart.
Now hit "Next" in the top right corner, and let's build our Hello World!
Code
Windmill gives you an online editor to work on your Scripts. The left-side is the editor itself. The right-side lets you preview the UI that Windmill will generate from the Script's signature - this will be visible to the users of the Script. You can easily preview that UI, provide input values, and test your script there.
We picked go
for this example, so Windmill provided some Go boilerplate. Let's
take a look:
package inner
import (
"fmt"
"rsc.io/quote"
// wmill "github.com/windmill-labs/windmill-go-client"
)
// the main must return (interface{}, error)
func main(x string, nested struct{ Foo string `json:"foo"` }) (interface{}, error) {
fmt.Println("Hello, World")
fmt.Println(nested.Foo)
fmt.Println(quote.Opt())
// v, _ := wmill.GetVariable("f/examples/secret")
return x, nil
}
In Windmill, scripts need to have a main
function that will be the script's
entrypoint. There are a few important things to note about the main
.
- The main arguments are used for generating the input spec of the Script, and the frontend that you see when running the Script as a standalone app.
- Type annotations are used to generate the UI form, and help pre-validate inputs. While not mandatory, they are highly recommended. You can customize the UI in later steps (but not change the input type!).
- The main of Go Scripts need to return
(interface{}, error)
.
Note that this Script is defined as a package named inner
. Windmill expects an
inner
package, so that cannot be changed.
Also take a look at the import statement line that's commented out. This is for importing the Windmill client, that is needed for example to access variables or resources. We won't go into that here.
Back to our Hello World. We can clear up unused import statements, change the
main to take in the user's name. Let's also return the name
, maybe we can use
this later if we use this Script within a Flow and need to pass it on.
package inner
import (
"fmt"
)
// the main must return (interface{}, error)
func main(name string) (interface{}, error) {
fmt.Printf("Hello, World. Oh, it's you %s. Greetings!", name)
return name, nil
}
Look at the UI preview on the right: it was updated to match the input signature. Run a preview to verify everything works. Now let's go to the last step: the "Advanced" settings.
Advanced settings
In this step, you can:
- Add a Description to the Script. This is where you can give instructions to users on how to run your Script. It supports markdown!
- Customize the Script Arguments. The UI is generated from the Script's main
function signature, but you can add additional constraints here. For example,
we could use the
Format
add a regex here to make sure users are providing a name with only alphanumeric characters:^[A-Za-z0-9]*$
. Let's still allow numbers in case you're some tech billionaire's kid.
We're done! Save your script. Note that Scripts are versioned in Windmill, and each script version is uniquely identified by a hash.
Run!
Now let's look at what users of this script will do. Click on the Run button to load this script. You'll see the user input form we defined earlier.
Fill in the input field, then hit "Run". You should see a run view, as well as your logs. All script runs are also available in the Runs menu on the left.
You can also chose to run your script from the CLI with the pre-made Command-Line Interface call.
What's next?
This script is a minimal working example, but there's a few more steps we need in a real-world use case:
- Pass variables and secrets to a script.
- Connect to resources.
- Run scripts or flows on a schedule.
- Compose scripts in Flows.
- You can share your scripts with the community on Windmill Hub. Once submitted, they will be verified by moderators before becoming available to everyone right within Windmill.