<a id="improve-code"></a>

# Improve the code

Use this path for changes to the Go service, charm, rock, or integration tests.
Run every test below for each code contribution. The final test rebuilds and
deploys the rock and charm.

## Prerequisites

Complete [Set up a development environment](https://canonical.com/juju/docs/gopkg-charm/latest/contribute/set-up-a-development-environment/index.html.md#set-up-a-development-environment) first.

The Go service is under `app/`. `app/rockcraft.yaml` packages it as a rock,
and the charm under `app/charm/` operates that image with Juju. For more details
on rocks and charms, see the [Rockcraft](https://ubuntu.com/containers/rockcraft/docs/latest/explanation/rocks/)
and [Charmcraft](https://canonical.com/juju/docs/charmcraft/4/)
documentation.

## Run all tests

Run the Go checks:

```bash
cd ~/gopkg-charm/app
test -z "$(gofmt -l .)"
go vet ./...
go build ./...
go test -race ./...
```

Next, run the charm checks:

```bash
cd ~/gopkg-charm/app/charm
tox -e lint,unit,static
```

Finally, rebuild, deploy, and test the rock and charm with the Juju
integration suite: `tox -e integration`, in a separate Multipass VM on an
AMD64 host prepared as [How to run the full Juju integration suite locally](https://canonical.com/juju/docs/gopkg-charm/latest/contribute/run-full-juju-integration-suite-locally/index.html.md#full-integration-suite-local) describes.

## Build and deploy from source

To test a change to
the service, the rock, or the charm by hand, build both locally and deploy the
result the same way. The recipes declare `amd64` and `arm64`, so this path
works on either architecture, unlike the published charm.

Build the rock:

```bash
cd ~/gopkg-charm/app
ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true rockcraft pack
```

`app/rockcraft.yaml` uses Rockcraft’s Go framework extension,
which builds the Go module and sets up the runtime; the extension is marked
experimental, so the environment variable opts in to it. The build runs inside
an LXD instance and fetches packages from the Ubuntu archive, so the first
build takes several minutes; if it fails with a network error from the
archive, run the command again.

The pack command produces `gopkg_0.1_<architecture>.rock` in `app/`. Kubernetes pulls
images from a registry, not from files, so push the rock to the local registry
that the MicroK8s `registry` add-on runs on port 32000, and check that the
registry lists the tag:

```bash
microk8s kubectl rollout status deployment/registry \
  -n container-registry --timeout=15m
rockcraft.skopeo copy --insecure-policy --dest-tls-verify=false --dest-no-creds \
  oci-archive:gopkg_0.1_$(dpkg --print-architecture).rock \
  docker://localhost:32000/gopkg:0.1
curl --fail --silent --show-error \
  http://localhost:32000/v2/gopkg/tags/list | grep -F '"0.1"'
```

`rockcraft.skopeo` is the copy of `skopeo` inside
the Rockcraft snap; its flags allow the plain-HTTP, unauthenticated local
registry.

Build the charm with Charmcraft’s Go framework extension, the counterpart of
the Rockcraft one:

```bash
cd ~/gopkg-charm/app/charm
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true charmcraft pack
```

Deploy the local charm with the image you pushed. Use a fresh model, or
destroy the tutorial’s first. The model constraint schedules the pods on your
machine’s architecture, which the rock you built requires:

```bash
juju add-model gopkg-k8s
juju set-model-constraints arch=$(dpkg --print-architecture)
juju deploy ./gopkg-k8s_$(dpkg --print-architecture).charm gopkg-k8s \
  --resource app-image=localhost:32000/gopkg:0.1
```

From here, follow the tutorial starting at [Deploy and verify gopkg-k8s on Kubernetes](https://canonical.com/juju/docs/gopkg-charm/latest/tutorials/deploy-and-verify-on-kubernetes/index.html.md#deploy-and-verify-on-kubernetes):
deploy and integrate the ingress integrator, set both hostname settings,
and verify the service.

## Update the documentation

Update the documentation when a code change affects configuration, deployment,
commands, or user-visible behavior. Follow [Improve the documentation](https://canonical.com/juju/docs/gopkg-charm/latest/contribute/improve-documentation/index.html.md#improve-documentation) for
those changes.
