diff --git a/docs/codelabs/genrule.md b/docs/codelabs/genrule.md index 2f8b6e5de..8b9f996b4 100644 --- a/docs/codelabs/genrule.md +++ b/docs/codelabs/genrule.md @@ -36,9 +36,9 @@ Duration: 3 Before we jump into writing custom build definitions, let me introduce you to `genrule()`, the generic build rule. Let's just create a new project and initialise Please in it: -``` -$ mkdir custom_rules && cd custom_rules -$ plz init --no_prompt +```bash +mkdir custom_rules && cd custom_rules +plz init --no_prompt ``` Then create a `BUILD` file in the root of the repository like so: @@ -54,13 +54,13 @@ genrule( ``` Then create file.txt: -``` -$ echo "the quick brown fox jumped over the lazy dog" > file.txt +```bash +echo "the quick brown fox jumped over the lazy dog" > file.txt ``` and build it: -``` +```bash $ plz build //:word_count Build finished; total time 70ms, incrementality 0.0%. Outputs: //:word_count: @@ -70,6 +70,14 @@ $ cat plz-out/gen/file.wc 1 9 45 file.txt ``` +### Troubleshooting: "can't store data at section "scm"" + +This message means the runner is using an older Please release that doesn’t understand the `[scm]` section in your `.plzconfig`, so parsing fails before any build work begins. + +**How to fix** +- Upgrade the Please version invoked in CI (pin the same version locally via `pleasew`, `setup-please`, or `PLZ_VERSION`). +- If upgrading immediately is impractical, temporarily remove or comment the `[scm]` block until the runner is updated. + ### So what's going on? Here we've used one of the built-in rules, `genrule()`, to run a custom command. `genrule()` can take a number of parameters, most notably: the name of the rule, the inputs (sources and dependencies), its outputs, and the command @@ -199,8 +207,12 @@ word_count( And check it still works: +```bash +plz build //:word_count +``` +The output: + ``` -$ plz build //:word_count Build finished; total time 30ms, incrementality 100.0%. Outputs: //:word_count: plz-out/gen/word_count.wc @@ -261,9 +273,10 @@ wc -w $@ ### `tools/BUILD` ```python -sh_binary( +filegroup( name = "wc", - main = "wc.sh", + srcs = ["wc.sh"], + binary = True, visibility = ["PUBLIC"], ) ``` @@ -392,3 +405,4 @@ If you create something you believe will be useful to the wider world, we might [pleasings](https://github.com/thought-machine/pleasings) repo! If you get stuck, jump on [gitter](https://gitter.im/please-build/Lobby) and we'll do our best to help you! + diff --git a/docs/codelabs/github_actions.md b/docs/codelabs/github_actions.md index 4e184b545..13e635a63 100644 --- a/docs/codelabs/github_actions.md +++ b/docs/codelabs/github_actions.md @@ -31,8 +31,7 @@ stuck you can find us on [gitter](https://gitter.im/please-build/Lobby)! ## GitHub Actions Duration: 5 -GitHub Actions is an extensible CI/CD platform provided by GitHub. -Compared to other CI/CD solutions, GitHub Actions allows you to build all kinds automations (called workflows) triggered by various events (eg. pushing code to a branch). +GitHub Actions is GitHub's built-in automation platform for CI/CD and other workflows. It runs workflows defined as YAML files in the .github/workflows directory, triggered by events (push, pull_request, schedule, manual, etc.). Workflows consist of jobs (run on hosted or self‑hosted runners) and steps that execute shell commands or reusable actions from the marketplace. Key benefits include tight GitHub integration, flexible triggers and matrices, a large action marketplace, and caching for faster builds. ### Setting up GitHub Actions diff --git a/docs/codelabs/go_intro.md b/docs/codelabs/go_intro.md index addbbd212..a439b3fc0 100644 --- a/docs/codelabs/go_intro.md +++ b/docs/codelabs/go_intro.md @@ -33,11 +33,11 @@ Duration: 2 The easiest way to get started is from an existing Go module: -```text -$ mkdir getting_started_go && cd getting_started_go -$ plz init -$ plz init plugin go -$ go mod init github.com/example/module +```bash +mkdir getting_started_go && cd getting_started_go +plz init +plz init plugin go +go mod init github.com/example/module ``` @@ -78,6 +78,16 @@ This configures the Go plugin, and makes the build definitions available in the automatically. Alternatively, if you're not using Go everywhere, you can remove the `preloadsubincludes` config and add `subinclude("///go//build_defs:go")` to each `BUILD` file that needs access to Go rules. +### Troubleshooting: "unknown rule go_binary" +Duration: 1 + +Seeing `unknown rule go_binary` (or similar for other Go rules) means the plugin was not loaded. Confirm the plugin target exists and re-run the init script if needed. + +**Fix checklist** +- `plz query config Plugin.go.Target` should report `//plugins:go`. +- Ensure `plugins/BUILD` is present and contains the Go plugin target. +- If `.plzconfig` was edited manually, re-run `plz init plugin go` or restore the snippet above. + Read the [config](/config.html) and [go plugin config](/plugins.html#go.config) docs for more information on configuration. @@ -143,8 +153,8 @@ Path = /usr/local/go/bin:/usr/local/bin:/usr/bin:/bin Additionally, from version 1.20, golang no longer includes the standard library with its distribution. To use 1.20 from the path with Please, you must install it. This can be done like so: -```text -$ GODEBUG="installgoroot=all" go install std +```bash +GODEBUG="installgoroot=all" go install std ``` ## Hello, world! @@ -158,8 +168,8 @@ package main import "fmt" -func main(){ - fmt.Println("Hello, world!") +func main() { + fmt.Println("Hello, world!") } ``` @@ -175,8 +185,14 @@ go_binary( ``` That's it! You can now run this with: + +```bash +plz run //src:main +``` + +You should see the output: + ```text -$ plz run //src:main Hello, world! ``` @@ -223,13 +239,18 @@ go_library( ) ``` -We can then build it like so: +Then run the following command to build the greetings package: + +```bash +plz build //src/greetings +``` + +You should see output similar to: ```text -$ plz build //src/greetings Build finished; total time 290ms, incrementality 50.0%. Outputs: //src/greetings:greetings: - plz-out/gen/src/greetings/greetings.a + plz-out/gen/src/greetings/greetings.a ``` Here we can see that the output of a `go_library` rule is a `.a` file which is stored in @@ -244,7 +265,7 @@ NB: This syntax can also be used on the command line e.g. `plz build //src/...` ## Using our new package Duration: 2 To maintain a principled model for incremental and hermetic builds, Please requires that rules are explicit about their -inputs and outputs. To use this new package in our "hello world" program, we have to add it as a dependency: +inputs and outputs. To use this new package in our "hello world" program, we have to add it as a dependency of our binary rule: ### `src/BUILD` ```python @@ -270,18 +291,20 @@ import ( "github.com/example/module/src/greetings" ) -func main(){ +func main() { fmt.Printf("%s, world!\n", greetings.Greeting()) } ``` -Give it a whirl: +Give it a whirl by running the following command: ```text $ plz run //src:main Bonjour, world! ``` +The greeting is selected at random, so your output may vary each time you run the command. + ## Testing our code Duration: 5 @@ -338,7 +361,7 @@ package greetings_test import ( "testing" - + // We now need to import the "production" package "github.com/example/module/src/greetings" ) diff --git a/docs/codelabs/k8s.md b/docs/codelabs/k8s.md index 29ab44ced..7c33439b4 100644 --- a/docs/codelabs/k8s.md +++ b/docs/codelabs/k8s.md @@ -38,20 +38,20 @@ you can find us on [gitter](https://gitter.im/please-build/Lobby)! ## Creating a service Duration: 5 -First up, let create a service to deploy. It's not really important what it does or what language we implement it in. -For the sake of this codelabs, we'll make a simple hello world HTTP service in Python. +First up, let's create a service to deploy. It's not really important what it does or what language we implement it in. +For this codelab, we'll make a simple hello world HTTP service in go. ### Initialising the project -``` -$ plz init -$ go mod init github.com/example/module -$ plz init plugin go +```bash +plz init +go mod init github.com/example/module +plz init plugin go ``` ### Set up the Go plugin Add a go toolchain to `third_party/go/BUILD` -```python +```go go_toolchain( name = "toolchain", version = "1.20", @@ -75,24 +75,23 @@ Create a file `hello_service/service.go`: package main import ( - "fmt" - "log" - "net/http" + "fmt" + "log" + "net/http" ) func main() { - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "This is my website!") - }) - - http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "Hello, HTTP!") - }) - - err := http.ListenAndServe(":8000", nil) - if err != nil { - log.Fatal("Error starting the server: ", err) - } + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "This is my website!") + }) + + http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, HTTP!") + }) + + if err := http.ListenAndServe(":8000", nil); err != nil { + log.Fatal("Error starting the server: ", err) + } } ``` @@ -107,14 +106,15 @@ go_binary( And test it works: +```bash +plz run //hello_service:hello_service && curl localhost:8000 +pkill hello_service ``` -$ plz run //hello_service & -[1] 28694 -$ curl localhost:8000 +The output should look like this: +```bash +[1] 28694 Hello, world! - -$ pkill hello_service [1]+ Terminated plz run //hello_service ``` @@ -136,9 +136,11 @@ RUN apt update -y && apt upgrade -y To use the docker build rules, we need to install the docker plugin, as well as the shell plugin which it requires: -`$ plz init plugin shell && plz init plugin docker` +```bash +plz init plugin shell && plz init plugin docker +``` -We can then build a set of scripts that help us build, and push our docker images: +We can then build a set of scripts that help us build, and push our docker images. Add the following to `common/docker/BUILD`: ```python docker_image( @@ -160,7 +162,7 @@ Build finished; total time 80ms, incrementality 40.0%. Outputs: As promised, the output of the docker image rule is a script that can build the docker image for you. We can have a look at what the script is doing: -``` +```bash $ cat plz-out/bin/common/docker/base.sh #!/bin/sh docker build -t please-examples/base:0d45575ad71adea9861b079e5d56ff0bdc179a1868d06d6b3d102721824c1538 \ @@ -173,8 +175,8 @@ back to this specific version of this image. - It's generated us a `tar.gz` containing all the other files we might need to build the Docker image. We can run this script to build the image and push it to the docker daemon as set in our docker env: -``` -$ plz run //common/docker:base +```bash +plz run //common/docker:base ``` ## Using our base image @@ -357,31 +359,30 @@ remote_file ( ``` And then we can start the cluster like so: -``` -$ plz run //third_party/binary:minikube -- start +```bash +plz run //third_party/binary:minikube -- start ``` ### Deploying our service First we need to push our images to minikube's docker. To do this we need to point `docker` at minikube: -``` -$ eval $(plz run //third_party/binary:minikube -- docker-env) +```bash +eval $(plz run //third_party/binary:minikube -- docker-env) ``` Then we can run our deployment scripts: -``` -$ plz run //hello_service/k8s:image_load && plz run //hello_service/k8s:k8s_push +```bash +plz run //hello_service/k8s:image_load && plz run //hello_service/k8s:k8s_push ``` And check they're working as we expected: ``` -$ kubectl port-forward service/hello-svc 8000:8000 & -[1] 25986 +$ kubectl port-forward service/hello-svc 8000:8000 && curl localhost:8000 -$ curl localhost:8000 +[1] 25986 Hello world! $ pkill kubectl @@ -395,8 +396,8 @@ Here we have learnt about the provided targets we need to run to get our changes bit of a ritual. Let's look at consolidating this into a single command. Luckily the generated targets are labeled so this is as simple as: -``` -$ plz run sequential --include docker-build --include k8s-push //hello_service/... +```bash +plz run sequential --include docker-build --include k8s-push //hello_service/... ``` We can then set up an alias for this in `.plzconfig`: @@ -410,8 +411,8 @@ positionallabels = true This is used like: -``` -$ plz deploy //hello_service/... +```bash +plz deploy //hello_service/... ``` ## Docker build and build systems @@ -451,4 +452,4 @@ There are two ways we anticipate these targets to be used as part of a CI/CD pip - The build server can be given access to the docker registry, and the images can be loaded directly with `:image_push`. - The build server can save the images out to an offline image tarball with `:image_save`. These can be exported as artifacts from the build server. Another stage of the CI/CD pipeline can then push these to the docker registry via -`docker load`. +`docker load`. diff --git a/docs/codelabs/plz_query.md b/docs/codelabs/plz_query.md index 097563242..35f4fc198 100644 --- a/docs/codelabs/plz_query.md +++ b/docs/codelabs/plz_query.md @@ -34,8 +34,13 @@ Duration: 2 For this codelab we will be using the Please codelabs repo: ```bash -$ git clone https://github.com/thought-machine/please-codelabs -Cloning into 'please-examples'... +git clone https://github.com/thought-machine/please-codelabs +``` + +The output should look something like this: + +```bash +Cloning into 'please-codelabs'... remote: Enumerating objects: 228, done. remote: Total 228 (delta 0), reused 0 (delta 0), pack-reused 228 Receiving objects: 100% (228/228), 38.23 KiB | 543.00 KiB/s, done. @@ -291,9 +296,11 @@ Build finished; total time 300ms, incrementality 100.0%. Outputs: This can be especially useful for separating out slow running tests: ```bash -plz test --exclude e2e +plz test --exclude my_label ``` +This will run all tests except those labeled with `my_label`. + ## What's next? Duration: 1 diff --git a/docs/codelabs/python_intro.md b/docs/codelabs/python_intro.md index 11c40c31b..b438e33c2 100644 --- a/docs/codelabs/python_intro.md +++ b/docs/codelabs/python_intro.md @@ -32,10 +32,10 @@ get stuck you can find us on [gitter](https://gitter.im/please-build/Lobby)! Duration: 2 Let's create a new project: -``` -$ mkdir getting_started_python && cd getting_started_python -$ plz init --no_prompt -$ plz init plugin python +```bash +mkdir getting_started_python && cd getting_started_python +plz init --no_prompt +plz init plugin python ``` ### A note about your Please PATH @@ -306,12 +306,11 @@ DisableVendorFlags = true We can now use this library in our code: ### `src/greetings/greetings.py` -```go +```python from numpy import random def greeting(): return random.choice(["Hello", "Bonjour", "Marhabaan"]) - ``` And add NumPy as a dependency: @@ -350,3 +349,7 @@ determine files changes since master, watch rules and build them automatically a `plz help`, and explore this rich set of commands! Otherwise, why not try one of the other codelabs! +, watch rules and build them automatically as things change and much more! Use +`plz help`, and explore this rich set of commands! + +Otherwise, why not try one of the other codelabs! diff --git a/docs/codelabs/using_plugins.md b/docs/codelabs/using_plugins.md index 1ecf44c47..88af3fbe6 100644 --- a/docs/codelabs/using_plugins.md +++ b/docs/codelabs/using_plugins.md @@ -38,8 +38,12 @@ check the directory we should have a config file, as well as the Please wrapper script `pleasew`: ```bash -$ plz init -$ tree -a +plz init +tree -a +``` + +The output should look like this: +```bash . ├── pleasew └── .plzconfig @@ -74,9 +78,12 @@ The easy way to install a plugin in your project is to use `plz init`. We'll use the Go plugin in this example: ```bash -$ plz init plugin go +plz init plugin go +tree -a +``` -$ tree -a +The output should look like this: +```bash . ├── pleasew ├── plugins