Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
219 commits
Select commit Hold shift + click to select a range
0796486
refactor: move client to separate package
henryde Jun 19, 2024
a0baddf
feat: project group bindings
henryde Jun 21, 2024
aa3165b
feat: building block resource
henryde Jun 28, 2024
0947438
fix: updated status codes
henryde Jul 4, 2024
7cdf4b7
fix: contentType for project user binding
malhussan Jul 9, 2024
af11b1d
fix: Set Accept header when getting a Building Block
sttomm Aug 2, 2024
4b23a7e
fix: http response code for building block creation is now 201
henryde Nov 14, 2024
f9c7a9e
fix: response codes for project and tenant creation
henryde Nov 15, 2024
4d96b33
feat: add basic implementation of tag_definitions data source
JohannesRudolph Nov 4, 2024
656d18b
feat: meshstack_tag_definition data source (GET)
malhussan Nov 5, 2024
28c9595
feat: meshstack_tag_definition resource
malhussan Nov 6, 2024
94e7d03
feat: set metadata.name automatically for tag_definition
henryde Nov 12, 2024
76f7c6c
refactor: check success by 2xx range
uleMeshcloud Dec 10, 2024
ba64475
feature: preview building blocks v2 resources
henryde Feb 25, 2025
e6df98a
feature: source provider configuration from environment
henryde Apr 17, 2025
b3b3f9a
fix: allow code inputs in buildingblock resource
malhussan Jul 31, 2025
2dc6030
feat: workspace data source
henryde Jul 23, 2025
6118432
feat: workspace resource
henryde Jul 23, 2025
ef46955
feat: meshstack_tenant_v4 resource
malhussan Nov 7, 2024
d71487c
fix: adapt tenant v4 client to actual implementation
henryde Jul 28, 2025
d919793
fix: adapt tenant_v4 resource to actual implementation
henryde Jul 28, 2025
9ac4d63
feat: buildingblock v2 polling for completion
malhussan Aug 11, 2025
0802352
feat: tenant v4 polling for completion
malhussan Aug 13, 2025
c67b1c9
chore: example for building_block_v2
malhussan Aug 14, 2025
3d2ffc9
add initial workspace bindings
OliverEsoterik Aug 18, 2025
36d7b91
additional changes from project to workspace, remove duplicates
OliverEsoterik Aug 18, 2025
0c6813b
duplicates and rrs resolved
OliverEsoterik Aug 18, 2025
5eb5713
remove typo in workspace group bindings
OliverEsoterik Aug 18, 2025
7f0a4f8
fmt
OliverEsoterik Aug 18, 2025
e36aba5
refactor: buildingblock status constants
malhussan Aug 18, 2025
54180a8
Merge pull request #44 from OliverEsoterik/workspace-bindings
j0g3sc Aug 25, 2025
d950611
refactor: move type out of loop
henryde Aug 29, 2025
a46ce61
fix: use pointers for optional tag value fields
henryde Aug 29, 2025
15dcd28
fix: add missing replicationKey to tag definition
henryde Aug 29, 2025
ac3b80b
chore: format all code according to go-fmt
nroi Sep 18, 2025
f8e67de
chore: fix typo in workspace.go (paylod)
nroi Sep 18, 2025
f4482d0
feat: support meshLandingZones
nroi Sep 10, 2025
4782eb0
chore: fix capitalization: AWS -> Aws etc.
nroi Sep 19, 2025
409ebff
fix: add missing landing zone status
nroi Sep 19, 2025
b6c1a50
chore: remove redundant MeshLandingZoneCreateMetadata
nroi Sep 19, 2025
e918df6
fix: fix landing zone status
nroi Sep 19, 2025
0244cf4
feat: implement support for meshPlatforms
nroi Sep 23, 2025
d3fa716
fix: make landingzone info_link optional
nroi Oct 20, 2025
746f2c3
chore: use new API endpoint for login and improve error message in ca…
j0g3sc Nov 3, 2025
1ee35ca
feat: add quota definitions to meshPlatforms
j0g3sc Nov 6, 2025
5460edf
feat: add metering config to platform
henryde Nov 12, 2025
8945872
feature: metering config for aks platforms
henryde Nov 13, 2025
1bf8944
refactor: separate platform configs by platform
henryde Nov 13, 2025
470415d
fix: correctly model nullable platform config fields
henryde Nov 13, 2025
0b7d8f8
refactor: common data structure for tenant tags
henryde Nov 13, 2025
eb66164
fix: small issues
henryde Nov 13, 2025
60a7c11
chore: generate docs
henryde Nov 17, 2025
88cfb6c
refactor: AksServicePrincipal
henryde Nov 17, 2025
0b00147
feat: added payment method resource and data endpoint
younGihan Nov 19, 2025
a59ffa1
Update client/payment_method.go
younGihan Nov 19, 2025
485b1fc
feat: removed workspace identifier for URL creation as not required
younGihan Nov 19, 2025
9928220
feat: quotas in landing zone data source
henryde Nov 19, 2025
deed5e7
Merge pull request #74 from meshcloud/feature/adding-payment-method
younGihan Nov 24, 2025
a7a35d7
feat: multi select building block inputs
henryde Nov 25, 2025
cd9785b
feat: integrations client
henryde Dec 5, 2025
4225ddc
feat: integrations data source
henryde Dec 11, 2025
ba0a686
fix: upstream api changed secret handling
henryde Dec 8, 2025
a2c08fd
fix: many golangci-lint issues, remove unused lookUpEndpoints in client
grubmeshi Dec 19, 2025
497bda6
feat: add meshstack_location resource
grubmeshi Dec 18, 2025
44caff0
feat: add metadata.owned_by_workspace for landing zones
nroi Jan 7, 2026
87903c1
fix: building block refs required by landing zones
henryde Jan 14, 2026
135bf96
refactor: read and return body already in doAuthenticatedRequest, ver…
grubmeshi Jan 9, 2026
5eebb12
refactor: use generate unmarshalBody(IfPresent)
grubmeshi Jan 9, 2026
8128350
refactor: use request modifiers and build http.Request only in doAuth…
grubmeshi Jan 9, 2026
63a8c50
refactor: remove deleteMeshObject and overeager status code validatio…
grubmeshi Jan 9, 2026
10f6f88
refactor: simplify client for workspace/project binding
grubmeshi Jan 9, 2026
41f210e
fix: provide (versioning) Accept header when calling DELETE endpoints
grubmeshi Jan 9, 2026
6bfabe8
refactor: simplify fetching paginated responses, add simplistic data …
grubmeshi Jan 9, 2026
b9fdd6f
refactor: use generic meshObjectClient to build MeshStackProviderClie…
grubmeshi Jan 9, 2026
bff3a79
refactor: simplify httpClient methods and url query handling
grubmeshi Jan 9, 2026
3c6c847
feat: change user agent such that the provider version is included
grubmeshi Jan 9, 2026
788b5d1
refactor: clean up client.NewClient() with factory methods and reflec…
grubmeshi Jan 9, 2026
69482ca
refactor: move MeshObjectClient into client/internal
grubmeshi Jan 10, 2026
88c6d71
refactor: use sub-clients in resources/data sources and helper config…
grubmeshi Jan 10, 2026
c30d092
feat: use gci to consistently format imports, improve Taskfile args h…
grubmeshi Jan 12, 2026
86cdac2
feat: properly implement logging using tflog from SDK, remove version…
grubmeshi Jan 12, 2026
276e69a
refactor: add util.PollAtMostFor(...).Until instead of cluttering up …
grubmeshi Jan 12, 2026
5188e2d
refactor: rename resource/datasource struct client fields (resolves r…
grubmeshi Jan 13, 2026
234279b
feat: platform type data sources and resource
henryde Jan 16, 2026
1eb24de
feat: add status field to platform type
henryde Jan 20, 2026
c073f53
fix: upstream structure has changed
henryde Jan 21, 2026
0b94a1b
feat: login via api token
henryde Jan 19, 2026
cd5eafa
feat: check meshStack version
henryde Jan 21, 2026
0f1e056
feat: add client/version package for parsing meshStack version
grubmeshi Jan 23, 2026
afc3e89
fix: use client/version
grubmeshi Jan 23, 2026
8752fc2
fix: subscription creation error cooldown nullable
henryde Jan 28, 2026
9f43b5e
feat: add `owned_by_workspace` for platform_type
nroi Jan 26, 2026
2595875
feat: custom platforms in meshstack_platform
henryde Feb 4, 2026
ae81c68
feat: service instance client
henryde Feb 6, 2026
745f0b9
feat: add support for `custom` landing zone
nroi Feb 12, 2026
03e67dc
refactor: rename name to better term 'kind' in internal.MeshObjectClient
grubmeshi Jan 15, 2026
cb8d596
refactor: move Secret DTO from platform to commonly shared client/typ…
grubmeshi Jan 21, 2026
d034bcb
feat: add ptr.To helper in client/types/ptr
grubmeshi Jan 21, 2026
758df6c
feat: support defining Go enum strings
grubmeshi Jan 30, 2026
1fd17bc
feat: add Variant[X, Y] in client/types/variant
grubmeshi Jan 30, 2026
90c3f91
feat: add mock client and resource test for meshstack_tag_definition
grubmeshi Feb 4, 2026
e61f057
feat: add mock client and resource/datasource test for meshstack_plat…
grubmeshi Feb 4, 2026
bac587f
feat: add mock client and extend resource test for meshstack_location
grubmeshi Feb 4, 2026
ad78a3e
feat: add mock client and resource/datasource test for meshstack_plat…
grubmeshi Feb 4, 2026
4f99ecf
feat: implement meshstack_integration resource with mock client
grubmeshi Feb 5, 2026
5ed8ad7
feat: use default runner in meshstack_integration if omitted, add ref…
grubmeshi Feb 8, 2026
8c37628
feat: add client.BuildingBlockDefinition(version) with model
grubmeshi Jan 10, 2026
f62ac8b
feat: add meshstack_building_block_definition
grubmeshi Feb 11, 2026
0dc1f1a
fix: handle empty argument/defaultValue correctly in SecretOrAny
grubmeshi Feb 11, 2026
91d1926
feat: add permissions to meshstack_building_block_definition.version_…
grubmeshi Feb 13, 2026
25726ac
fix: missing/wrong azure config fields
henryde Feb 17, 2026
92797c7
feat: add parameter support to ServiceInstance resource
sttomm Feb 17, 2026
79b2afd
fix: make BBD notification_subscribers a set and handle removal of in…
grubmeshi Feb 17, 2026
3edb184
feat: add `owned_by_workspace` for meshstack_location
nroi Feb 17, 2026
09bfce5
feat: make meshPlatform related resources GA
sttomm Feb 16, 2026
cb7aa23
refactor: remove apiVersion and kind from platform related terraform …
sttomm Feb 18, 2026
415725f
feat: support write-only ephemeral secrets in meshstack_platform reso…
grubmeshi Feb 18, 2026
7b0b057
refactor: rename to StringSetElem
grubmeshi Feb 19, 2026
a54b425
fix: properly handle null/empty in BBD, simplify set handling in gene…
grubmeshi Feb 24, 2026
76f4f65
feat: add pre_run_script field to meshstack_building_block_definition…
JohannesRudolph Mar 9, 2026
65c842a
fix: address review comments and CI failures for pre_run_script field
Copilot Mar 11, 2026
35e74a5
feat: Add aws_identity_store support to meshstack_platform resource
Copilot Mar 11, 2026
c6d8961
fix: use existing role refs and remove wrong mst- prefix docs
JohannesRudolph Mar 12, 2026
807b3b2
fix: only support the actually valid output IO types
sttomm Mar 18, 2026
73b7ccb
fix: fix platform config boolean flags for AWS and AzureRG (#139)
grubmeshi Apr 1, 2026
0c4bd12
refactor: remove api_version/kind, extract client interfaces
grubmeshi Apr 9, 2026
2094fae
feat: add meshstack_tenants data source
grubmeshi Apr 9, 2026
0301314
feat: expose platform access_information in resource and data source
grubmeshi Apr 14, 2026
88732b6
feat: add refName property to AzureDevOps Building Block Definition i…
sttomm Apr 2, 2026
536cadd
refactor: use Go 1.26 new(expression) feature
grubmeshi Apr 23, 2026
dbece1a
feat: Removes Azure Blueprint and OpenShift template support
tfelix May 4, 2026
c6cbc5a
feat: add meshstack_api_key resource
grubmeshi Apr 29, 2026
a684374
test: add cross-workspace BBD listing test
grubmeshi May 5, 2026
afbfed3
refactor: use Authoriztion.Header abstraction, improve error message
grubmeshi May 8, 2026
02a757c
feat: retry GET/PUT requests and POST login and add internal.HttpClie…
grubmeshi May 8, 2026
91c85f4
feat: adapt building_block_v2 to moved createdOn field in upstream API
nroi May 6, 2026
135a43b
fix: adapt building block definition after changes in upstream API
nroi May 7, 2026
686a3bc
fix: do not expose lifecycle in BB schema (resource/datasource)
grubmeshi May 12, 2026
c9fcd89
fix: add lifecycle state tracking to building_block_v2
nroi May 18, 2026
23b2ddc
chore: document all lifecycle states for building_block_v2
nroi May 18, 2026
dddf8ff
chore: add test for BB deletion
nroi May 19, 2026
dfc7983
fix: migrate building block target references
nroi May 15, 2026
abd332c
feat: introduce MESHSTACK_SKIP_VERSION_CHECK to skip version check
nroi May 21, 2026
58adb1b
fix: change input/output structure from array to map
nroi May 28, 2026
34926e5
feat: add meshstack_building_block_runner resource
malhussan May 26, 2026
92bffda
fix: revert "change input/output structure from array to map"
nroi May 29, 2026
4d82399
fix: change input/output structure from array to map
nroi May 28, 2026
9ac5638
feat: add purge_on_delete support to meshstack_building_block_v2
grubmeshi Jun 2, 2026
24bc91c
fix: align BB v2 client with embedded-secret sensitive inputs
grubmeshi Jun 2, 2026
359aaab
feat: add ALL capability to building block runner implementation types
tfelix Jun 3, 2026
0e53c9f
chore: bump to v0.22.0 release, require newest meshstack
grubmeshi Jun 10, 2026
fa000ba
feat: allow MANAGED_BUILDINGBLOCK_SAVE on building block permissions
grubmeshi Jun 16, 2026
745865e
feat: add support for EntraId meshIntegrations
j0g3sc Jun 15, 2026
5d89105
refactor: generic DoRequest/DoAuthorizedRequest http client API
grubmeshi Jun 1, 2026
4481ff5
refactor: normalize buildingblock → building_block file & symbol names
grubmeshi Jun 1, 2026
cd3a815
feat: implement meshstack_building_block resource
grubmeshi Jun 1, 2026
ed533bf
feat: meshstack_building_blocks data source
grubmeshi Jun 25, 2026
66d8a17
fix: retry DELETE and widen retry budget for backend restarts
grubmeshi Jul 6, 2026
b244bac
fix: prepare for upcoming WAITING_FOR_APPROVAL building block status
sttomm Jul 7, 2026
1c138e6
feat: allow to manage display_order value for building block definiti…
j0g3sc Jul 3, 2026
37932cf
fix(building_block_definition): send display_order 0 so it round-trips
grubmeshi Jul 9, 2026
3fda00f
fix(building_block): tolerate transient FAILED during a force-purge d…
grubmeshi Jul 14, 2026
2eff7cf
feat: add meshTenant UUID as BB input assignmentType
j0g3sc Jul 16, 2026
38137db
refactor: rename MESH_TENANT_UUID to MESHSTACK_TENANT_ID
j0g3sc Jul 16, 2026
f7313c9
refactor: rename MESHSTACK_TENANT_ID assignment type to MESHSTACK_TEN…
grubmeshi Jul 17, 2026
868021d
feat: allow all dedicated (not NONE) assignment types for outputs on …
j0g3sc Jul 20, 2026
fb1aa92
refactor: consolidate meshObject reference handling behind a single m…
grubmeshi Jul 16, 2026
05780df
refactor: consolidate client ref DTOs into shared NamedRef/UuidRef
grubmeshi Jul 17, 2026
71d0aa0
refactor: model platform aws/gcp role mappings as sets
grubmeshi Jul 17, 2026
8464031
feat: back meshstack_tenant and meshstack_tenants with the meshTenant…
grubmeshi Jul 20, 2026
3cd7346
fix: source meshstack_tenant status from the v4 tenantName field
grubmeshi Jul 22, 2026
c045ae8
fix: track only user-declared tags on taggable resources
tfelix Jul 22, 2026
74b5fa9
feat: send building block definition dependencies as dependencyDefini…
grubmeshi Jul 21, 2026
f95cf67
refactor: derive List query params from struct json tags in WithUrlQuery
grubmeshi Jul 22, 2026
66fe815
fix: make declared outputs work on manual building blocks
vzaslavsky Jul 21, 2026
958d448
feat!: rename meshstack_tenant status.tenant_identifier to tenant_name
grubmeshi Jul 23, 2026
dc0621d
chore: apply go1.26 go fix idioms
grubmeshi Jul 23, 2026
2999fae
feat: add List wrappers to platform and landing zone clients
grubmeshi Jul 20, 2026
ee819a2
feat: add meshstack_platforms and meshstack_landingzones data sources
grubmeshi Jul 20, 2026
6a10431
feat: expiry date on workspace bindings
vzaslavsky Jul 23, 2026
a6d35b7
feat: read back effective tenant quotas from meshTenant v4 status.quotas
tfelix Jul 22, 2026
6ae439d
feat: model tenant quotas as maps (requested_quotas / applied_quotas)
tfelix Jul 23, 2026
acd3c49
feat: model tenant quotas as structured value objects and warn on unr…
tfelix Jul 24, 2026
8807963
fix: correct tenant quota approval semantics, cover landing-zone defa…
tfelix Jul 29, 2026
82ae669
chore: fix acceptance tests timeouts at tenant deletion
j0g3sc Jul 30, 2026
7d06765
feat!: reference parent building blocks by ref, and add the building …
grubmeshi Aug 11, 2026
e44839a
feat!: remove the deprecated spec.quotas from meshstack_tenant
grubmeshi Aug 10, 2026
6a54f75
feat!: promote meshstack_tenant to the meshTenant v4 GA API
grubmeshi Aug 12, 2026
6b4fee9
fix: honor MESHSTACK_SKIP_VERSION_CHECK before requesting /mesh/info
JohannesRudolph Aug 18, 2026
cc1894e
fix: tolerate unknown spec values and ref-shaped meshTenant v4 reads
grubmeshi Aug 19, 2026
2cd35d4
Merge origin/main into the v0.24.5 fix branch
grubmeshi Aug 19, 2026
5a27467
feat: manage a landing zone's restricted flag via spec.restricted
nroi Aug 13, 2026
7eb1881
refactor: model landing zone spec.restricted as a plain bool
nroi Aug 14, 2026
b732181
feat: add meshStack instance data source
j0g3sc Aug 13, 2026
dd03c54
refactor: address review comments regarding mesh_info struct and client
j0g3sc Aug 13, 2026
7ff0696
refactor: expose meshstack_instance four-eyes state as enabled_featur…
j0g3sc Aug 13, 2026
2d757f7
fix: put CHANGELOG entry to new version as 0.24.4 is released already.
j0g3sc Aug 13, 2026
2302b71
feat: support adopting an existing identity provider on entra id inte…
malhussan Aug 24, 2026
350ef89
fix!: move the entra id redirect url to status
malhussan Aug 24, 2026
1d49c39
feat: add an optional building block name template
grubmeshi Aug 25, 2026
7601c58
feat: expose building block definition approvals and drift schedule
nroi Aug 31, 2026
6fb6fa8
feat: read a meshStack tag as a building block definition input
tfelix Sep 1, 2026
b188bbb
feat: support optional Building Block Definition inputs
j0g3sc Aug 20, 2026
fb71cad
build: move to go 1.27 and pin golangci-lint as a go tool
grubmeshi Sep 2, 2026
a242aa1
feat: support JSON_SCHEMA building block definition inputs
tfelix Aug 27, 2026
6954a55
refactor: derive definition input types from the IO types
tfelix Sep 1, 2026
ce90235
docs: describe JSON_SCHEMA inputs as the sub-form they are
tfelix Sep 1, 2026
fe5bd16
feat: support conditional inputs
j0g3sc Sep 8, 2026
cf78ea1
refactor: rename the JSON_SCHEMA definition input type to JSON
tfelix Sep 8, 2026
c13fb74
feat: import the meshStack API client from the Terraform provider
grubmeshi Sep 18, 2026
720acdb
refactor: make the imported client a package of this module
grubmeshi Sep 18, 2026
c89eb7a
feat: set up the Go module that builds the meshStack API client
grubmeshi Sep 18, 2026
ddb57ee
feat: resolve a meshStack session from settings, profiles and credent…
grubmeshi Sep 18, 2026
577cff3
feat: add the meshstack command line interface
grubmeshi Sep 18, 2026
ea3b94d
feat: warn when a newer CLI release is on GitHub
grubmeshi Sep 18, 2026
33125be
test: drive the login command against a local meshStack
grubmeshi Sep 18, 2026
297c2c4
feat: take the profile name from a --profile flag
grubmeshi Sep 18, 2026
e3659cb
feat: create the profile a login names when it does not exist yet
grubmeshi Sep 18, 2026
b8e05c3
feat: report the resolved credential while the workspace is resolved
grubmeshi Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path // empty' | { read -r f; [[ \"$f\" == *.go ]] && cd \"$CLAUDE_PROJECT_DIR\" && go tool golangci-lint fmt \"$f\"; } 2>/dev/null || true"
}
]
}
]
}
}
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# The build only needs the Go sources, go.mod and go.sum. Everything below would
# otherwise be copied into the build context and invalidate its cache.
.git/
.github/
dist/
.nix-go/
meshstack
.env
.vscode/
.idea/
*.md
85 changes: 85 additions & 0 deletions .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Modelled on meshcloud/building-block-runner's build-images.yml, minus the Docker Hub push.
name: Build Image

env:
REGISTRY: ghcr.io
IMAGE_NAMESPACE: ${{ github.repository_owner }}
IMAGE_NAME: meshstack-cli

on:
# Called by the release workflow, so a tagged release publishes the matching image.
workflow_call:
inputs:
version:
description: "Release version to tag the image with, e.g. v1.2.3"
required: true
type: string
# A push to main refreshes :main, so an image exists before the first release does.
push:
branches:
- main
# Builds the image but does not push it, so a broken Dockerfile fails review rather than main.
pull_request:
paths:
- 'Dockerfile'
- '.github/workflows/build-image.yml'
- 'go.mod'
- 'go.sum'
- '**/*.go'

jobs:
build:
name: Build and push image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

# Computed here rather than with docker/metadata-action, to keep the set of pinned
# actions small.
- name: Determine version and tags
id: meta
env:
# Read through the environment, because a tag name may hold shell metacharacters and
# ${{ }} would paste them into the script this job runs.
VERSION_INPUT: ${{ inputs.version }}
run: |
if [ -n "${VERSION_INPUT}" ]; then
version="${VERSION_INPUT}"
tags="${REGISTRY}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:${version}"
tags="${tags},${REGISTRY}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:latest"
elif [ "${{ github.ref }}" = "refs/heads/main" ]; then
version="main-$(git rev-parse --short HEAD)"
tags="${REGISTRY}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:main"
tags="${tags},${REGISTRY}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:${version}"
else
version="pr-${{ github.event.number }}"
tags="${REGISTRY}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:${version}"
fi
echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "tags=${tags}" >> "$GITHUB_OUTPUT"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
build-args: |
VERSION=${{ steps.meta.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
44 changes: 44 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Releases the meshstack CLI when a tag matching "v*" is pushed.
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: read

jobs:
goreleaser:
name: GoReleaser
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Let goreleaser read older tags, which it needs for the changelog.
fetch-depth: 0
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: 'go.mod'
cache: true
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3
with:
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Publishes the image for the same tag. Separate job so a failing image build does
# not take the archives down with it.
image:
name: Image
needs: [ goreleaser ]
permissions:
contents: read
packages: write
uses: ./.github/workflows/build-image.yml
with:
version: ${{ github.ref_name }}
87 changes: 87 additions & 0 deletions .github/workflows/test-acceptance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# The acceptance suite needs a whole meshStack backend, so it cannot run here. This workflow asks
# the private meshStack mono repo to run it and report the result back as a check run.
name: Acceptance Tests

# The push trigger catches a CLI/backend regression on main, before a release tag.
on:
pull_request_target:
push:
branches:
- main
# TEMPORARY, delete before merge. A pull_request_target run takes this file from the base
# branch, where it does not exist yet, so a push is the only trigger that can try the
# dispatcher out on its own pull request.
- feature/scaffold-cli
Comment thread
grubmeshi marked this conversation as resolved.

permissions:
contents: read

jobs:
# No `name:`, unlike test.yml's jobs: nothing gates on this check. The gating check is
# "Acceptance Tests (meshStack backend)", which meshfed-release posts.
request:
runs-on: ubuntu-latest
env:
SATELLITE_REF: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.ref || github.ref_name }}

# The run has to be in our own repository, and on a pull request the head branch has to live
# here too — which means its author has write access, so the code under test is code we
# already trust.
DISPATCH: ${{ github.repository_owner == 'meshcloud' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) }}

# This workflow MUST NOT check out the pull request, and has no `actions/checkout` for that
# reason. `pull_request_target` runs in the base repo's context with its secrets, so checking
# out contributor code here would be the classic "pwn request" hole.
steps:
- name: Explain a skipped fork pull request
if: env.DISPATCH != 'true' && github.event_name == 'pull_request_target'
env:
BASE_REPO: ${{ github.repository }}
run: echo "::notice::Acceptance tests are not dispatched for a fork pull request. A maintainer has to adopt the branch into $BASE_REPO before the suite can run against it."

# Downscoped to `actions: write` at mint time, so a later widening of the app cannot leak
# into this workflow.
- name: Mint a token for the dispatch
id: token
if: env.DISPATCH == 'true'
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
# The secret holds the numeric app id, not a client id: the action reads `client-id` or
# the deprecated `app-id` into one value, and GitHub takes either as the JWT issuer. The
# name stays because it is an organization secret every satellite reads.
client-id: ${{ secrets.SATELLITE_GH_APP_ID }}
private-key: ${{ secrets.SATELLITE_GH_APP_PRIVATE_KEY }}
owner: meshcloud
repositories: meshfed-release
permission-actions: write

# meshfed-release pairs a satellite branch with a same-named branch of its own, so the
# dispatch names that branch rather than always `develop`: a `workflow_dispatch` reads the
# workflow file from the ref it is given, and `develop` would run the orchestration that is
# already merged. This token may dispatch workflows there and read nothing, so trying the
# dispatch is the only branch lookup available.
#
# `$SATELLITE_REF` reaches the script through the environment, never as a `${{ }}` expression
# GitHub substitutes into the script text: a branch named `$(id)` would otherwise run as a
# command.
- name: Request the acceptance run
if: env.DISPATCH == 'true'
env:
GH_TOKEN: ${{ steps.token.outputs.token }}
run: |
set -euo pipefail
request() {
gh workflow run ci-satellite.yml \
--repo meshcloud/meshfed-release \
--ref "$1" \
-f repo=meshstack-cli \
-f branch_name="$SATELLITE_REF"
}
if request "$SATELLITE_REF"; then
orchestrated_from="$SATELLITE_REF"
else
echo "::notice::meshfed-release has no branch $SATELLITE_REF to dispatch, so develop orchestrates this run."
request develop
orchestrated_from=develop
fi
echo "::notice::Requested an acceptance run for $SATELLITE_REF, orchestrated from meshfed-release $orchestrated_from. The result arrives as the \"Acceptance Tests (meshStack backend)\" check."
101 changes: 101 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Tests

# No `paths-ignore` on either trigger, deliberately: a workflow skipped that way never reports its
# checks, so a required check on it stays "expected" forever and blocks the merge. A skipped *job*
# reports success; a skipped *workflow* does not.
on:
pull_request:
push:
branches:
- main

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Go Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: 'go.mod'
cache: true
- run: go mod tidy
- run: go build -v ./...
- name: git diff
run: |
git diff --compact-summary --exit-code || \
(echo; echo "Unexpected difference in directories after 'go mod tidy'. Run 'go mod tidy' command and commit."; exit 1)

golangci:
needs: [ build ]
name: Go Lint and Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: 'go.mod'
cache: true
# Built here rather than downloaded by the action below: golangci-lint's formatters use the
# go/format compiled into the binary, so the formatting they enforce comes from the Go release
# that built the linter. The tool directive in go.mod is the single pin.
- name: Build the pinned golangci-lint
run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint
- name: golangci-lint
uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
with:
# The step above already installed it; the action is here for the annotations it puts on
# the pull request diff, which a bare `run:` does not produce.
install-mode: none
- name: Suggest fix command on failure
if: failure()
run: |
echo "::error::Linting or formatting issues detected. Run 'task lint -- --fix' locally to automatically fix these issues, then commit the changes."

test:
name: Go Test
needs: [ build ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: 'go.mod'
cache: true
# Binary coverage data (GOCOVERDIR format) rather than a text profile, because only the
# binary form merges with the acceptance run's coverage. `-coverpkg=./...` has to match what
# meshfed-release runs the acceptance suite with, or the merged figure is a ratio over two
# different denominators.
- name: Run unit tests with gotestsum
run: |
mkdir -p covdata/unit
go tool gotestsum --junitfile junit.xml --format testdox -- \
-coverpkg=./... ./... -args -test.gocoverdir="$PWD/covdata/unit"

# meshfed-release finds this by the pull request head sha, so it has to be uploaded from a
# `pull_request` job. The contract with that side is the artifact name `covdata-unit` and
# covmeta.*/covcounters.* at its root, which naming the directory gives and a glob would nest.
- name: Upload unit coverage data
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: covdata-unit
path: covdata/unit
retention-days: 3

- name: Report unit coverage
if: always()
run: |
if ! ls covdata/unit/covmeta.* >/dev/null 2>&1; then
echo "Unit coverage: no data produced." >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
go tool covdata textfmt -i=covdata/unit -o=unit.txt
echo "Unit coverage: $(go tool cover -func=unit.txt | tail -1 | awk '{print $NF}')" >> "$GITHUB_STEP_SUMMARY"
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Binary produced by 'task build'
/meshstack

# Release artifacts produced by goreleaser
/dist/

# Go environment created by the Nix dev shell (flake.nix shellHook)
/.nix-go/

# Store symlink left behind by 'nix build'
/result
/result-*

# Local meshStack credentials, read by the Taskfile's dotenv
.env

# A go.work names other checkouts by path, so it describes one developer's or one CI runner's
# directory layout and never the repository. meshfed-release's go-satellite plugin writes one when
# it runs the acceptance suite, and the meshStack Terraform provider writes one to build against a
# paired branch of this repository.
go.work
go.work.sum

# What the CI test command leaves behind when you reproduce it locally.
covdata/
junit.xml
unit.txt

# Editor and IDE directories
.vscode/
.idea/

# Per-developer Claude Code settings; .claude/settings.json is shared and committed
.claude/settings.local.json
Loading
Loading