From 801bacbc52768e8e05ce491a90d467eb336736a6 Mon Sep 17 00:00:00 2001 From: andres-nullplatform Date: Thu, 13 Aug 2026 16:39:30 -0500 Subject: [PATCH 1/3] Revert "fix(k8s): stop hardcoding the CloudWatch logging annotations" --- CHANGELOG.md | 1 - k8s/deployment/templates/deployment.yaml.tpl | 6 ++++++ scheduled_task/deployment/templates/deployment.yaml.tpl | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d90dffb..d657fe53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -- Remove unused cloudwatch annotations from deployment objects ## [1.15.1] - 2026-08-12 - Fix: gRPC additional ports on k8s scopes now leave the declared port free for the application, so a gRPC server can bind the port configured in the scope instead of failing to start with "address already in use". gRPC ports now work the same way HTTP ones already did diff --git a/k8s/deployment/templates/deployment.yaml.tpl b/k8s/deployment/templates/deployment.yaml.tpl index 0e513c1e..c9843915 100644 --- a/k8s/deployment/templates/deployment.yaml.tpl +++ b/k8s/deployment/templates/deployment.yaml.tpl @@ -74,6 +74,12 @@ spec: {{- end }} {{- end }} annotations: + nullplatform.logs.cloudwatch: 'true' + nullplatform.logs.cloudwatch.log_group_name: {{ .namespace.slug }}.{{ .application.slug }} + nullplatform.logs.cloudwatch.log_stream_log_retention_days: '7' + nullplatform.logs.cloudwatch.log_stream_name_pattern: >- + type=${type};application={{ .application.id }};scope={{ .scope.id }};deploy={{ .deployment.id }};instance=${instance};container=${container} + nullplatform.logs.cloudwatch.region: {{ .region }} {{- $global := index .k8s_modifiers "global" }} {{- if $global }} {{- $annotations := index $global "annotations" }} diff --git a/scheduled_task/deployment/templates/deployment.yaml.tpl b/scheduled_task/deployment/templates/deployment.yaml.tpl index ef797236..c556acfd 100644 --- a/scheduled_task/deployment/templates/deployment.yaml.tpl +++ b/scheduled_task/deployment/templates/deployment.yaml.tpl @@ -96,6 +96,12 @@ spec: {{- end }} {{- end }} annotations: + nullplatform.logs.cloudwatch: 'true' + nullplatform.logs.cloudwatch.log_group_name: {{ .namespace.slug }}.{{ .application.slug }} + nullplatform.logs.cloudwatch.log_stream_log_retention_days: '7' + nullplatform.logs.cloudwatch.log_stream_name_pattern: >- + type=${type};application={{ .application.id }};scope={{ .scope.id }};deploy={{ .deployment.id }};instance=${instance};container=${container} + nullplatform.logs.cloudwatch.region: us-east-1 {{- $global := index .k8s_modifiers "global" }} {{- if $global }} {{- $annotations := index $global "annotations" }} From 4ec6803b2d5e4e76d8638d75333a7e07db3bc5b2 Mon Sep 17 00:00:00 2001 From: sebasnallar Date: Thu, 3 Sep 2026 18:53:10 -0300 Subject: [PATCH 2/3] fix(publish): underscore image names + existing_tag recovery dispatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1.16.1 failed to publish scheduled-task and containers-datadog: the ECR repositories don't exist, and the names were wrong anyway — the images are scopes/scheduled_task and scopes/containers_datadog (underscores, matching the source directories). Renames image_name, the artifact registration repository and the release table for both. Also adds a workflow_dispatch existing_tag input: a tag push runs the workflow at the tagged commit, so a fix on main can never reach an already-pushed tag without a dispatch path. CLI install moves from the alpha-packages channel to the released 2.10.0. Co-Authored-By: Claude Fable 5 --- .github/workflows/publish-images.yml | 55 +++++++++++++++++----------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/.github/workflows/publish-images.yml b/.github/workflows/publish-images.yml index 6792a521..31dbba8d 100644 --- a/.github/workflows/publish-images.yml +++ b/.github/workflows/publish-images.yml @@ -5,8 +5,15 @@ name: publish-images # Same mold as scopes-lambda (publish-image.yml), fanned out to the 3 images: # # scopes/containers <- k8s/ (base; FROM worker-bridge + tooling) -# scopes/scheduled-task <- scheduled_task/ (leaner) -# scopes/containers-datadog <- containers + datadog/ overlay (metric) +# scopes/scheduled_task <- scheduled_task/ (leaner) +# scopes/containers_datadog <- containers + datadog/ overlay (metric) +# +# Image names use underscores, matching the source directories — the ECR +# repositories must exist under these exact names (ECR never creates on push). +# +# Recovery / backfill: dispatch with existing_tag to publish an already-pushed +# tag with the CURRENT workflow (a tag push runs the workflow at the tagged +# commit, so fixes on main never reach old tags without this). # # The datadog overlay is FROM the containers base (which bakes the whole repo # into /app/pkg), so it must be pushed first — its build `needs: containers` and @@ -21,6 +28,12 @@ on: push: tags: - 'v*' + workflow_dispatch: + inputs: + existing_tag: + description: 'Publish an existing tag with the current workflow (recovery/backfill)' + required: true + type: string permissions: id-token: write # OIDC against AWS @@ -35,7 +48,7 @@ jobs: context: . submodules: true dockerfile: docker/containers.Dockerfile - tag: ${{ github.ref_name }} + tag: ${{ inputs.existing_tag || github.ref_name }} secrets: aws_role_arn: ${{ secrets.AWS_ROLE_ARN_ECR_PUSH }} @@ -47,8 +60,8 @@ jobs: NULLPLATFORM_API_KEY: ${{ secrets.NP_API_KEY }} NP_ARTIFACT_NRN: ${{ vars.NP_ARTIFACT_NRN }} steps: - - name: Install np CLI (alpha-packages build) - run: curl -s https://cli.nullplatform.com/install.sh | VERSION=alpha-packages sh + - name: Install np CLI (2.10.0) + run: curl -s https://cli.nullplatform.com/install.sh | VERSION=2.10.0 sh - name: Register scopes/containers image artifact (visible to everyone) run: | np artifact create \ @@ -63,11 +76,11 @@ jobs: scheduled-task: uses: nullplatform/actions-nullplatform/.github/workflows/docker-build-push-ecr.yml@main with: - image_name: scopes/scheduled-task + image_name: scopes/scheduled_task context: . submodules: true dockerfile: docker/scheduled-task.Dockerfile - tag: ${{ github.ref_name }} + tag: ${{ inputs.existing_tag || github.ref_name }} secrets: aws_role_arn: ${{ secrets.AWS_ROLE_ARN_ECR_PUSH }} @@ -79,15 +92,15 @@ jobs: NULLPLATFORM_API_KEY: ${{ secrets.NP_API_KEY }} NP_ARTIFACT_NRN: ${{ vars.NP_ARTIFACT_NRN }} steps: - - name: Install np CLI (alpha-packages build) - run: curl -s https://cli.nullplatform.com/install.sh | VERSION=alpha-packages sh - - name: Register scopes/scheduled-task image artifact (visible to everyone) + - name: Install np CLI (2.10.0) + run: curl -s https://cli.nullplatform.com/install.sh | VERSION=2.10.0 sh + - name: Register scopes/scheduled_task image artifact (visible to everyone) run: | np artifact create \ --nrn "$NP_ARTIFACT_NRN" \ --type oci_image \ --registry public.ecr.aws \ - --repository nullplatform/scopes/scheduled-task \ + --repository nullplatform/scopes/scheduled_task \ --digest "${{ needs.scheduled-task.outputs.image_digest }}" \ --visible-to "organization=*" @@ -96,12 +109,12 @@ jobs: needs: containers uses: nullplatform/actions-nullplatform/.github/workflows/docker-build-push-ecr.yml@main with: - image_name: scopes/containers-datadog + image_name: scopes/containers_datadog context: . submodules: true dockerfile: docker/containers-datadog.Dockerfile - tag: ${{ github.ref_name }} - build_args: BASE_VERSION=${{ github.ref_name }} + tag: ${{ inputs.existing_tag || github.ref_name }} + build_args: BASE_VERSION=${{ inputs.existing_tag || github.ref_name }} secrets: aws_role_arn: ${{ secrets.AWS_ROLE_ARN_ECR_PUSH }} @@ -113,15 +126,15 @@ jobs: NULLPLATFORM_API_KEY: ${{ secrets.NP_API_KEY }} NP_ARTIFACT_NRN: ${{ vars.NP_ARTIFACT_NRN }} steps: - - name: Install np CLI (alpha-packages build) - run: curl -s https://cli.nullplatform.com/install.sh | VERSION=alpha-packages sh - - name: Register scopes/containers-datadog image artifact (visible to everyone) + - name: Install np CLI (2.10.0) + run: curl -s https://cli.nullplatform.com/install.sh | VERSION=2.10.0 sh + - name: Register scopes/containers_datadog image artifact (visible to everyone) run: | np artifact create \ --nrn "$NP_ARTIFACT_NRN" \ --type oci_image \ --registry public.ecr.aws \ - --repository nullplatform/scopes/containers-datadog \ + --repository nullplatform/scopes/containers_datadog \ --digest "${{ needs.containers-datadog.outputs.image_digest }}" \ --visible-to "organization=*" @@ -137,7 +150,7 @@ jobs: runs-on: ubuntu-24.04 env: GH_TOKEN: ${{ github.token }} - TAG: ${{ github.ref_name }} + TAG: ${{ inputs.existing_tag || github.ref_name }} REGISTRY: public.ecr.aws/nullplatform DIGEST_CONTAINERS: ${{ needs.containers.outputs.image_digest }} DIGEST_SCHEDULED: ${{ needs.scheduled-task.outputs.image_digest }} @@ -147,8 +160,8 @@ jobs: run: | SECTION=$(printf '## Artifacts\n\n| Image | Digest | Pinned reference |\n|---|---|---|\n| `%s:%s` | `%s` | `%s@%s` |\n| `%s:%s` | `%s` | `%s@%s` |\n| `%s:%s` | `%s` | `%s@%s` |' \ "$REGISTRY/scopes/containers" "$TAG" "$DIGEST_CONTAINERS" "$REGISTRY/scopes/containers" "$DIGEST_CONTAINERS" \ - "$REGISTRY/scopes/scheduled-task" "$TAG" "$DIGEST_SCHEDULED" "$REGISTRY/scopes/scheduled-task" "$DIGEST_SCHEDULED" \ - "$REGISTRY/scopes/containers-datadog" "$TAG" "$DIGEST_DATADOG" "$REGISTRY/scopes/containers-datadog" "$DIGEST_DATADOG") + "$REGISTRY/scopes/scheduled_task" "$TAG" "$DIGEST_SCHEDULED" "$REGISTRY/scopes/scheduled_task" "$DIGEST_SCHEDULED" \ + "$REGISTRY/scopes/containers_datadog" "$TAG" "$DIGEST_DATADOG" "$REGISTRY/scopes/containers_datadog" "$DIGEST_DATADOG") # Drafts are not resolvable via releases/tags/:tag — list and filter. RELEASE_ID=$(gh api "repos/$GITHUB_REPOSITORY/releases" --paginate \ From 2ad46632e01d9715eb595f233a149e5511c696f5 Mon Sep 17 00:00:00 2001 From: sebasnallar Date: Thu, 3 Sep 2026 19:12:00 -0300 Subject: [PATCH 3/3] fix(publish): build backfill dispatches from the tag's commit Passes ref: existing_tag to docker-build-push-ecr (via actions-nullplatform#100) so a recovery dispatch builds the tagged content, not the main head the dispatch ran from. Co-Authored-By: Claude Fable 5 --- .github/workflows/publish-images.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish-images.yml b/.github/workflows/publish-images.yml index 31dbba8d..4e7c9b87 100644 --- a/.github/workflows/publish-images.yml +++ b/.github/workflows/publish-images.yml @@ -49,6 +49,7 @@ jobs: submodules: true dockerfile: docker/containers.Dockerfile tag: ${{ inputs.existing_tag || github.ref_name }} + ref: ${{ inputs.existing_tag || '' }} secrets: aws_role_arn: ${{ secrets.AWS_ROLE_ARN_ECR_PUSH }} @@ -81,6 +82,7 @@ jobs: submodules: true dockerfile: docker/scheduled-task.Dockerfile tag: ${{ inputs.existing_tag || github.ref_name }} + ref: ${{ inputs.existing_tag || '' }} secrets: aws_role_arn: ${{ secrets.AWS_ROLE_ARN_ECR_PUSH }} @@ -114,6 +116,7 @@ jobs: submodules: true dockerfile: docker/containers-datadog.Dockerfile tag: ${{ inputs.existing_tag || github.ref_name }} + ref: ${{ inputs.existing_tag || '' }} build_args: BASE_VERSION=${{ inputs.existing_tag || github.ref_name }} secrets: aws_role_arn: ${{ secrets.AWS_ROLE_ARN_ECR_PUSH }}