Skip to content

ci(ff): support feature freeze automation#7339

Open
fr4nc1sc0-r4m0n wants to merge 13 commits into
elastic:mainfrom
fr4nc1sc0-r4m0n:feature/support-ff-fleet-server
Open

ci(ff): support feature freeze automation#7339
fr4nc1sc0-r4m0n wants to merge 13 commits into
elastic:mainfrom
fr4nc1sc0-r4m0n:feature/support-ff-fleet-server

Conversation

@fr4nc1sc0-r4m0n

@fr4nc1sc0-r4m0n fr4nc1sc0-r4m0n commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What is the problem this PR solves?

Fleet Server release automation still relies on Makefile-based scripts and external CLI tools. This PR migrates the feature-freeze release workflow to pure Go Mage targets so release steps can run without depending on hub, gh, sed, yq, or Python.

This continues the work from #6584, rebased onto current main with merge conflicts resolved.

How does this PR solve the problem?

  • Adds Mage release commands for major/minor and patch workflows (release:runMajorMinor, release:runPatch, and supporting targets)
  • Extracts release logic into dev-tools/mage/release/ (release.go, git.go, github.go), aligned with elastic-agent and beats
  • Keeps thin mage release:* wrappers in magefile.go that delegate to the release package
  • Makes all release steps idempotent so workflows can be safely re-run after partial failure or CI retry:
    • updateVersion no-ops when DefaultVersion already matches
    • updateMergify no-ops when the backport rule already exists
    • createBranch checks out an existing branch instead of failing
    • commitAll skips when there are no changes
    • push succeeds when the remote is already up to date
    • createPR returns an existing open PR for the same head/base
  • Adds DRY_RUN mode for safe local testing
  • Documents the workflow, idempotency guarantees, and package layout in RELEASE.md

How to test this PR locally

export PROJECT_OWNER="your-user"
export CURRENT_RELEASE="9.5.0-test"
export GITHUB_TOKEN=$(gh auth token)
export DRY_RUN=true

# Dry run major/minor workflow
mage release:runMajorMinor

# Review changes
git diff

# Run release unit tests
cd dev-tools && go test ./mage/release/... -count=1

Re-run the same commands to confirm idempotent behavior (no duplicate branches, commits, PRs, or file changes).

Design Checklist

  • I have ensured my design is stateless and will work when multiple fleet-server instances are behind a load balancer.
  • I have or intend to scale test my changes, ensuring it will work reliably with 100K+ agents connected.
  • I have included fail safe mechanisms to limit the load on fleet-server: rate limiting, circuit breakers, caching, load shedding, etc.

Checklist

  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have made corresponding change to the default configuration files
  • I have added tests that prove my fix is effective or that my feature works
  • I have added an entry in ./changelog/fragments using the changelog tool

Validation

  • Merged latest main and resolved go.mod / go.sum conflicts
  • cd dev-tools && go test -race -count=1 ./mage/release/... passes
  • go build -tags mage succeeds with thin magefile wrappers

Related issue: https://github.com/elastic/observability-robots/issues/3404

@fr4nc1sc0-r4m0n fr4nc1sc0-r4m0n requested a review from a team as a code owner July 9, 2026 09:30
@fr4nc1sc0-r4m0n fr4nc1sc0-r4m0n added Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team skip-changelog labels Jul 9, 2026
@fr4nc1sc0-r4m0n fr4nc1sc0-r4m0n added Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team skip-changelog labels Jul 9, 2026
@fr4nc1sc0-r4m0n fr4nc1sc0-r4m0n self-assigned this Jul 9, 2026
@snyk-io

snyk-io Bot commented Jul 9, 2026

Copy link
Copy Markdown

⚠️ Snyk checks are incomplete.

Status Scan Engine Critical High Medium Low Total (0)
⚠️ Open Source Security 0 0 0 0 See details
⚠️ Licenses 0 0 0 0 See details

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@mergify

mergify Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

This pull request does not have a backport label. Could you fix it @fr4nc1sc0-r4m0n? 🙏
To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-./d./d is the label to automatically backport to the 8./d branch. /d is the digit
  • backport-active-all is the label that automatically backports to all active branches.
  • backport-active-8 is the label that automatically backports to all active minor branches for the 8 major.
  • backport-active-9 is the label that automatically backports to all active minor branches for the 9 major.

@fr4nc1sc0-r4m0n fr4nc1sc0-r4m0n added backport-active-9 Automated backport with mergify to all the active 9.[0-9]+ branches backport-8.19 Automated backport to the 8.19 branch labels Jul 9, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Allow release workflows to be safely retriggered by no-oping when the
target version is already applied, reusing existing branches and open
PRs, and skipping empty commits.
Move release workflow logic into a dedicated package aligned with
elastic-agent and beats, leaving thin mage release:* wrappers in
magefile.go.
@github-actions

This comment has been minimized.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

TL;DR

:gcloud: Cloud e2e FIPS Test failed before running the E2E tests because the deployed Cloud resource did not expose a Fleet endpoint: Terraform’s fleet_url output was empty, and .buildkite/scripts/cloud_e2e_test.sh exits with status 1 in that case.

Remediation

  • Retry the Cloud e2e FIPS job if this was a transient Cloud/integrations-server provisioning issue.
  • If it repeats, inspect the Cloud deployment/integrations-server logs for the custom FIPS image docker.elastic.co/beats-ci/elastic-agent-cloud-fips:pr-7339-bf17d6ffe9cf; the next fix should make that deployment expose integrations_server.endpoints.fleet before mage test:cloudE2ERun starts.
Investigation details

Root Cause

The immediate failure is a configuration/infrastructure failure in the Cloud FIPS deployment, not a test assertion failure. The step script reads fleet_url from Terraform and exits when it is empty:

# .buildkite/scripts/cloud_e2e_test.sh:31-45
FLEET_SERVER_URL=$(terraform output --raw --state=dev-tools/cloud/terraform/terraform.tfstate fleet_url)
...
if [[ "${FLEET_SERVER_URL}" == "" ]]; then
    message="FLEET_SERVER_URL is empty, cloud e2e tests cannot be executed"
    ...
    exit 1
fi

That output is derived from the integrations server Fleet endpoint:

# dev-tools/cloud/terraform/outputs.tf:28-30
output "fleet_url" {
  value = ec_deployment.deployment.integrations_server.endpoints != null ? ec_deployment.deployment.integrations_server.endpoints.fleet : ""
}

The captured teardown log shows fleet_url = "" -> null while the integrations server still had a generic HTTPS endpoint, then the job exited 1. That means the job stopped before mage test:cloudE2ERun could execute.

Evidence

Changes to Outputs:
  - fleet_url        = "" -> null
  - integrations_url = "(b58eb8a8e21842a1919a99ef...st2.gcp.elasticcloud.com/redacted)" -> null
...
Destroy complete! Resources: 1 destroyed.
^^^ +++
🚨 Error: The command exited with status 1
^^^ +++
user command error: exit status 1

Verification

  • Not run locally; this requires the Buildkite Cloud/FIPS provisioning environment and the prefetched job log only contains teardown plus the final exit status, not the earlier deployment startup logs.

Follow-up

No existing flaky-test issue was found for this Cloud e2e FIPS/empty fleet_url failure pattern.


What is this? | From workflow: PR Buildkite Detective

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.

Enable gomoddirectives replace-local so the dev-tools submodule
replace required by mage release imports passes golangci-lint.
The root go.mod replaces dev-tools with a local path. Docker layer
caching must include dev-tools/go.mod and go.sum so go mod download
can resolve the replaced module.
@mergify

mergify Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it @fr4nc1sc0-r4m0n? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

git fetch upstream
git checkout -b feature/support-ff-fleet-server upstream/feature/support-ff-fleet-server
git merge upstream/main
git push upstream feature/support-ff-fleet-server

Comment thread go.mod
github.com/elastic/elastic-agent-client/v7 v7.18.1
github.com/elastic/elastic-agent-libs v0.44.0
github.com/elastic/elastic-agent-system-metrics v0.14.4
github.com/elastic/fleet-server/dev-tools v0.0.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way we can avoid polluting the project's go.mod?

if err != nil {
return fmt.Errorf("failed to checkout existing branch: %w", err)
}
fmt.Printf("✓ Checked out existing branch: %s\n", branchName)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should't checkout branches. Maybe delete them first?

Comment thread magefile.go
if err != nil {
return err
}
return release.CreateReleaseBranch(cfg, ".", os.Getenv("DRY_RUN") == "true")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return release.CreateReleaseBranch(cfg, ".", os.Getenv("DRY_RUN") == "true")
return release.CreateReleaseBranch(cfg, ".", envToBool("DRY_RUN"))

Comment thread magefile.go
if err != nil {
return err
}
return release.CreateReleasePR(cfg, ghClient, os.Getenv("DRY_RUN") == "true")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do have envToBool as a helper available.

}

// PreparePatchRelease prepares files for a patch release.
func PreparePatchRelease(cfg *ReleaseConfig) error {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not doing anything besides setting the version of *ReleaseCofnig

}

// RunPatchRelease orchestrates the complete patch release workflow.
func RunPatchRelease(cfg *ReleaseConfig, dryRun bool) error {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a no-op?

return nil
}

err := g.repo.Push(&git.PushOptions{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What credentials are we using here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-8.19 Automated backport to the 8.19 branch backport-active-9 Automated backport with mergify to all the active 9.[0-9]+ branches skip-changelog Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants