Skip to content

Commit 470f618

Browse files
authored
[minor] compose reconcile (#28)
1 parent 1ac5475 commit 470f618

7 files changed

Lines changed: 116 additions & 45 deletions

File tree

README.md

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
11
# sitectl-drupal
22

3-
A [sitectl](https://sitectl.libops.io) plugin for Drupal websites. It works with the [LibOps Drupal template](https://github.com/libops/drupal).
3+
`sitectl-drupal` simplifies the creation and operation of repositories created using the [LibOps Drupal template](https://github.com/libops/drupal). It provides sitectl commands for Drush, development mode, config sync, login links, validation, health checks, and component-driven customization.
44

5-
The docs are available at [https://sitectl.libops.io/plugins/drupal](https://sitectl.libops.io/plugins/drupal)
5+
Documentation: https://sitectl.libops.io/plugins/drupal
6+
7+
## Requirements
8+
9+
- [`sitectl`](https://sitectl.libops.io/install).
10+
- Docker with the Compose v2 plugin for local Drupal sites.
11+
- No additional app-plugin dependency beyond core `sitectl`.
12+
13+
## Quick Start
14+
15+
Create a local Drupal site from the matching template:
16+
17+
```bash
18+
sitectl create drupal/default \
19+
--template-repo https://github.com/libops/drupal \
20+
--path ./my-drupal-site \
21+
--type local \
22+
--checkout-source template \
23+
--default-context
24+
```
25+
26+
The template README is at https://github.com/libops/drupal.
27+
28+
## Basic Operations
29+
30+
Use [`sitectl compose`](https://sitectl.libops.io/commands/compose) to start or inspect the stack:
31+
32+
```bash
33+
sitectl compose up --remove-orphans -d
34+
```
35+
36+
Use [`sitectl healthcheck`](https://sitectl.libops.io/commands/healthcheck) and [`sitectl validate`](https://sitectl.libops.io/commands/validate) to check the site:
37+
38+
```bash
39+
sitectl healthcheck
40+
sitectl validate
41+
```
42+
43+
Use [`sitectl image`](https://sitectl.libops.io/commands/image) for local image or build-arg overrides:
44+
45+
```bash
46+
sitectl image set --tag drupal=nginx-1.30.3-php84
47+
```
48+
49+
Use [`sitectl set`](https://sitectl.libops.io/commands/set) and [`sitectl converge`](https://sitectl.libops.io/commands/converge) for component changes:
50+
51+
```bash
52+
sitectl set dev-mode enabled
53+
sitectl converge
54+
```
55+
56+
See the [Drupal plugin docs](https://sitectl.libops.io/plugins/drupal) for Drush, sync, ULI, and Drupal-specific workflows.
57+
58+
## License
59+
60+
`sitectl-drupal` is licensed under the MIT License.

cmd/create.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,39 @@ func createDefinition() plugin.CreateSpec {
2020
DockerComposeRepo: drupalCreateRepo,
2121
DockerComposeBranch: drupalCreateBranch,
2222
DockerComposeBuild: []string{
23-
"mkdir -p ./certs",
24-
"id -u > ./certs/UID",
2523
"docker compose pull --ignore-buildable --ignore-pull-failures",
26-
"docker compose build --pull",
24+
"docker compose build",
25+
},
26+
Images: []plugin.ComposeImageSpec{
27+
{Service: "drupal", Image: "libops/drupal:php84", BuildPolicy: plugin.BuildPolicyIfNotPresent},
2728
},
2829
DockerComposeInit: []string{
2930
"if [ ! -f .env ]; then cp sample.env .env; fi",
3031
"mkdir -p ./certs",
3132
"id -u > ./certs/UID",
3233
"docker compose run --rm -e HOST_UID=\"$(id -u)\" -e HOST_GID=\"$(id -g)\" init",
3334
},
34-
DockerComposeUp: []string{"docker compose up --remove-orphans -d"},
35-
DockerComposeDown: []string{"docker compose down"},
36-
DockerComposeRollout: []string{"./scripts/rollout.sh"},
35+
InitArtifacts: []plugin.InitArtifact{
36+
{Path: ".env"},
37+
{Path: "certs/cert.pem"},
38+
{Path: "certs/privkey.pem"},
39+
{Path: "certs/rootCA.pem"},
40+
{Path: "certs/rootCA-key.pem"},
41+
{Path: "certs/UID", ValueFrom: plugin.InitArtifactValueFromHostUID},
42+
{Path: "secrets/DB_ROOT_PASSWORD"},
43+
{Path: "secrets/DRUPAL_DEFAULT_ACCOUNT_PASSWORD"},
44+
{Path: "secrets/DRUPAL_DEFAULT_DB_PASSWORD"},
45+
{Path: "secrets/DRUPAL_DEFAULT_SALT"},
46+
},
47+
DockerComposeUp: []string{"docker compose up --remove-orphans -d"},
48+
DockerComposeDown: []string{"docker compose down"},
49+
DockerComposeRollout: []string{
50+
"docker compose pull --ignore-buildable --quiet || docker compose pull --ignore-buildable || true",
51+
"docker compose build --pull",
52+
"docker compose up --remove-orphans --wait --pull missing --quiet-pull -d",
53+
"docker compose exec -T drupal drush updb -y || echo \"Drupal database update skipped or failed\"",
54+
"docker compose exec -T drupal drush cr || echo \"Drupal cache rebuild skipped or failed\"",
55+
"docker compose up --remove-orphans --wait --pull missing --quiet-pull -d",
56+
},
3757
}
3858
}

cmd/create_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,26 @@ func TestCreateDefinition(t *testing.T) {
2626
if spec.DockerComposeInit[3] != "docker compose run --rm -e HOST_UID=\"$(id -u)\" -e HOST_GID=\"$(id -g)\" init" {
2727
t.Fatalf("expected init service command, got %+v", spec.DockerComposeInit)
2828
}
29+
if len(spec.InitArtifacts) == 0 || spec.InitArtifacts[0].Path != ".env" {
30+
t.Fatalf("expected explicit init artifacts, got %+v", spec.InitArtifacts)
31+
}
32+
var foundUID bool
33+
for _, artifact := range spec.InitArtifacts {
34+
if artifact.Path == "certs/UID" && artifact.ValueFrom == plugin.InitArtifactValueFromHostUID {
35+
foundUID = true
36+
}
37+
}
38+
if !foundUID {
39+
t.Fatalf("expected host UID init artifact, got %+v", spec.InitArtifacts)
40+
}
41+
if len(spec.Images) != 1 || spec.Images[0].Service != "drupal" || spec.Images[0].Image != "libops/drupal:php84" {
42+
t.Fatalf("expected Drupal image spec, got %+v", spec.Images)
43+
}
2944
if len(spec.DockerComposeUp) == 0 || spec.DockerComposeUp[0] != "docker compose up --remove-orphans -d" {
3045
t.Fatalf("expected compose up create command, got %+v", spec.DockerComposeUp)
3146
}
32-
if len(spec.DockerComposeRollout) == 0 || spec.DockerComposeRollout[0] != "./scripts/rollout.sh" {
33-
t.Fatalf("expected rollout script command, got %+v", spec.DockerComposeRollout)
47+
if len(spec.DockerComposeRollout) == 0 || spec.DockerComposeRollout[0] == "./scripts/rollout.sh" {
48+
t.Fatalf("expected inline rollout commands, got %+v", spec.DockerComposeRollout)
3449
}
3550
}
3651

cmd/healthcheck.go

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,14 @@
11
package cmd
22

3-
import (
4-
"github.com/libops/sitectl/pkg/config"
5-
"github.com/libops/sitectl/pkg/healthcheck"
6-
"github.com/libops/sitectl/pkg/plugin"
7-
sitevalidate "github.com/libops/sitectl/pkg/validate"
8-
"github.com/spf13/cobra"
9-
)
10-
11-
type drupalHealthcheckRunner struct{}
12-
13-
func (drupalHealthcheckRunner) BindFlags(cmd *cobra.Command) {}
14-
15-
func (drupalHealthcheckRunner) Run(cmd *cobra.Command, ctx *config.Context) ([]sitevalidate.Result, error) {
16-
results := []sitevalidate.Result{
17-
healthcheck.CheckHTTP(cmd.Context(), "http:drupal", healthcheck.PublicURLFromEnv(ctx, "http", "drupal.traefik.me")),
18-
}
19-
20-
checker, err := healthcheck.NewDockerChecker(ctx)
21-
if err != nil {
22-
return nil, err
23-
}
24-
defer checker.Close()
25-
26-
results = append(results,
27-
checker.CheckMariaDB(cmd.Context(), "mariadb"),
28-
checker.CheckSolrCore(cmd.Context(), "solr", "default"),
29-
)
30-
return results, nil
31-
}
32-
33-
var _ plugin.HealthcheckRunner = drupalHealthcheckRunner{}
3+
import "github.com/libops/sitectl/pkg/plugin"
4+
5+
var drupalHealthcheckRunner = plugin.StandardComposeWebHealthcheck(plugin.StandardComposeWebHealthcheckOptions{
6+
AppService: "drupal",
7+
HTTPName: "http:drupal",
8+
DefaultScheme: "http",
9+
DefaultDomain: "drupal.traefik.me",
10+
DatabaseService: "mariadb",
11+
CheckDatabaseDependency: true,
12+
SolrService: "solr",
13+
SolrCore: "default",
14+
})

cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func RegisterCommands(s *plugin.SDK) error {
3434
ReadyMessage: "Drupal is ready for use through sitectl.",
3535
})
3636
sdk.RegisterDebugRunner(&drupalDebugRunner{})
37-
sdk.RegisterHealthcheckRunner(drupalHealthcheckRunner{})
37+
sdk.RegisterHealthcheckRunner(drupalHealthcheckRunner)
3838
sdk.AddCommand(drushCmd)
3939
sdk.AddCommand(loginCmd)
4040
sdk.AddCommand(syncCmd)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/libops/sitectl-drupal
33
go 1.26.1
44

55
require (
6-
github.com/libops/sitectl v0.22.0
6+
github.com/libops/sitectl v0.25.1
77
github.com/spf13/cobra v1.10.2
88
gopkg.in/yaml.v3 v3.0.1
99
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
8282
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
8383
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
8484
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
85-
github.com/libops/sitectl v0.22.0 h1:fB0ybMVDP3DIjg1Miym/HmqKCKwanmznTPPJo1cXZSc=
86-
github.com/libops/sitectl v0.22.0/go.mod h1:uoXxmr3TSUYVgcWxwcFSOiDUmmKQW2ASr856dk/9yd8=
85+
github.com/libops/sitectl v0.25.1 h1:h2e5znVwyLHQ27p59hdqhHtdxpGxj8Sr8W2cxMmf0vU=
86+
github.com/libops/sitectl v0.25.1/go.mod h1:uoXxmr3TSUYVgcWxwcFSOiDUmmKQW2ASr856dk/9yd8=
8787
github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
8888
github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
8989
github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU=

0 commit comments

Comments
 (0)