Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f5ca4b5
Add Android support for custom host vitals (#49696)
nulmete Jul 29, 2026
451319b
Hide Account Provisioning on Fleet free (#50130)
MagnusHJensen Jul 29, 2026
9c2ef14
Scrub device policy responses in Fleet Desktop (#50094)
lucasmrod Jul 29, 2026
e6118b4
extra error message checks and correct escaping in error message (#50…
MagnusHJensen Jul 29, 2026
699bdb5
Prepare to archive fleet-gitops repo (#50134)
lukeheath Jul 29, 2026
1a0f010
Fix gitops not updating FMA installer (#50000)
jkatz01 Jul 29, 2026
40b901c
Fix broken gitops-auto-complete build. (#50081)
getvictor Jul 29, 2026
f67d9a5
Update Fleet-maintained apps (#50138)
fleet-release Jul 29, 2026
b7654a5
Custom windows update article (#49961)
harrisonravazzolo Jul 29, 2026
54b32dd
Fix typo in LinkedIn tracking workflow section (#50151)
DanFashauer Jul 29, 2026
3405bdc
feat(pg): PostgreSQL datastore compatibility layer
dnplkndll May 14, 2026
92b33f8
ci(pg): test-go-postgres + validate-pg-compat gates; private-repo ski…
dnplkndll May 14, 2026
ee71edd
tools(pg): pgcompat validators — primary-keys, schema-drift, column-d…
dnplkndll May 14, 2026
5149e27
tools(pg): pg-compat-harness — live URL-filter regression matrix
dnplkndll May 14, 2026
fbc598c
tools(pg): pg-index-translate — MySQL schema KEY → PG CREATE INDEX
dnplkndll May 14, 2026
4baaa70
docs(pg): operator deploy guide for PostgreSQL mode
dnplkndll May 14, 2026
e657f57
fix(pg-goose): ORDER BY version_id DESC, id DESC in PG dbVersionQuery
dnplkndll May 14, 2026
3032242
fix(pg-baseline): reassign function ownership alongside tables/sequen…
dnplkndll May 14, 2026
51009d0
docs(pg): pin seedPGMigrationTable version-order invariant in a comment
dnplkndll May 14, 2026
1d1daf9
baseline(pg): regenerate from prod and bump marker to 20260513210000
dnplkndll May 14, 2026
2e1a8ff
fix(pg): explicit-type NULL in setup_experience UNION legs for COALESCE
dnplkndll May 14, 2026
effa2ee
test(pg-harness): add orbit + osquery POST endpoint coverage
dnplkndll May 14, 2026
919942c
fix(pg): add windows_mdm_commands to knownPrimaryKeys
dnplkndll May 14, 2026
6dbfc3f
fix(pg): allowlist hosts.orbit_debug_until drift (regen after next de…
dnplkndll May 14, 2026
0a49252
fix(pg): support new vpp_client_users table and recent migrations
dnplkndll May 23, 2026
8554d14
fix(pg): implement pgMigrationHelper and isPostgres for Postgres migr…
dnplkndll May 23, 2026
e1eece9
fix(pg): make renumbered migrations idempotent and PostgreSQL compatible
dnplkndll May 23, 2026
e2f7119
baseline(pg): regenerate baseline schema and bump marker to 202605221…
dnplkndll May 23, 2026
b7e3c01
fix(pg): remove stale column drift entries from allowlist
dnplkndll May 23, 2026
f3d9cf6
fix(pg): make May–June upstream migrations PostgreSQL-compatible
dnplkndll Jun 12, 2026
41d5d38
baseline(pg): regenerate baseline schema and bump marker to 202606090…
dnplkndll Jun 12, 2026
3af7561
fix(pg): port new upstream datastore queries to PostgreSQL
dnplkndll Jun 12, 2026
56b9347
fix(pg): port Jun 9–11 upstream changes to PostgreSQL
dnplkndll Jun 12, 2026
7e24ba5
chore(pg): drop build/CI meta-files owned by the ledoent branch
dnplkndll Jun 12, 2026
3c8400e
fix(pg): rebind: cast $N * INTERVAL multiplier to float8, not timesta…
dnplkndll Jul 8, 2026
c363b50
fix(pg): SCEP expiry query: satisfy PostgreSQL GROUP BY strictness
dnplkndll Jul 8, 2026
c8aea7c
fix(pg): Windows MDM cleanup and re-enrollment DELETEs: cross-dialect…
dnplkndll Jul 8, 2026
4fbf2c2
test(pg): regression-cover previously broken MDM statements in the PG…
dnplkndll Jul 8, 2026
3f1d929
ci(pg): retry go mod download in PG workflows
dnplkndll Jul 8, 2026
441b9e0
ci(pg): run PG compat on direct pushes to feat/pg-compat-rebased
dnplkndll Jul 8, 2026
6c12aae
chore(pg): drop remaining ledoent-owned CI meta-files
dnplkndll Jul 8, 2026
59a7591
fix(pg): port June–July upstream changes after rebase onto 5cd8edbfb5
dnplkndll Jul 26, 2026
d7c898e
fix(pg): unblock CVE meta load — conditional upsert on PG, 10-minute …
dnplkndll Jul 26, 2026
e2cc492
fix(pg): port June–July upstream migrations to PostgreSQL; replay the…
dnplkndll Jul 26, 2026
c78cd85
baseline(pg): regenerate baseline schema and bump marker to 202607241…
dnplkndll Jul 26, 2026
1470360
fix(pg): boolean CASE branches in GetHostMDM connected_to_fleet
dnplkndll Jul 27, 2026
994e2fd
chore(pg): tidy tools/upgrade go.sum for pgx deps
dnplkndll Jul 27, 2026
9c44899
ci(pg): satisfy zizmor — bump harden-runner, no credential persistence
dnplkndll Jul 27, 2026
3de3b0b
docs(pg): remediation plan for 2026-07-27 adversarial review
dnplkndll Jul 27, 2026
42c6cae
fix(pg): phase 1 of review remediation — honest test gate + 8 correct…
dnplkndll Jul 27, 2026
1f75a7b
docs(pg): mark phase 1 complete; record prod table-ownership gotcha
dnplkndll Jul 27, 2026
1384d21
fix(pg): host policies ORDER BY must not reference SELECT alias in ex…
dnplkndll Jul 27, 2026
3778543
docs(pg): detailed phase 2 execution plan with prod pre-flight facts
dnplkndll Jul 27, 2026
1eee7e2
fix(pg): phase 2 of review remediation — schema parity + constraint v…
dnplkndll Jul 27, 2026
026cfd2
docs(pg): phase 2 deployed and verified on prod
dnplkndll Jul 27, 2026
f50785c
docs(pg): detailed phase 3 execution plan
dnplkndll Jul 27, 2026
84059cf
fix(pg): phase 3.1 — driver refuses silent semantic changes
dnplkndll Jul 27, 2026
cda0c58
fix(pg): phase 3.2 — migration-runner robustness
dnplkndll Jul 27, 2026
1462b2d
fix(pg): phase 3.3 — validator completion
dnplkndll Jul 27, 2026
eceff9a
fix(pg): phase 3.4 — PG failover fail-fast + drop pre-rename activity…
dnplkndll Jul 27, 2026
2362b49
chore(pg): phase 3.5 — hygiene and docs truth pass
dnplkndll Jul 27, 2026
35ec59c
baseline(pg): regenerate after phase 3; bump marker to 20260727210000
dnplkndll Jul 27, 2026
5881f38
docs(pg): findings reconciliation table — all 25 findings dispositioned
dnplkndll Jul 27, 2026
8a45a89
fix(pg): drift backstop compares against DB max applied version, not …
dnplkndll Jul 27, 2026
70893f5
fix(pg): re-review must-fixes — swap-drop 42P01, ESP tri-state, updat…
dnplkndll Jul 28, 2026
84512c9
chore(pg): remove re-review agent's probe test file
dnplkndll Jul 28, 2026
ef84074
docs(pg): record re-review outcome — 3 must-fixes closed same day
dnplkndll Jul 28, 2026
82b9f48
chore(pg): extract shared allowlist loader; mark swap-SQL migration c…
dnplkndll Jul 28, 2026
06de3b6
test(pg): host helper for smoke tests; MySQL upsert parity; touch-col…
dnplkndll Jul 28, 2026
1d19260
docs(pg): refresh validator/generator inventory
dnplkndll Jul 28, 2026
8dc8a32
feat(pg): phase 4 — full dual-dialect datastore gate, no CI filter
dnplkndll Jul 29, 2026
95755b3
fix(pg): CI-surfaced phase 4 fallout — advisory lock for DeviceLock r…
dnplkndll Jul 29, 2026
0aaccf1
fix(pg): gate the last direct-MySQL test helpers behind MYSQL_TEST
dnplkndll Jul 29, 2026
3faeee0
feat(pg): rebase onto upstream/main (84 commits); port backdated migr…
dnplkndll Jul 29, 2026
f52c3f5
chore(pg): tidy gitops-auto-complete go.sum against fork root module
dnplkndll Jul 29, 2026
694aa2c
docs(pg): record Phase 4 mid-phase rebase and backdated-migration port
dnplkndll Jul 29, 2026
58158c7
fix(pg): let the below-marker backstop admit declared porting wrappers
dnplkndll Jul 29, 2026
abddb9d
docs(pg): document the porting-wrapper pattern for back-dated migrations
dnplkndll Jul 29, 2026
97d87d7
fix(pg): dedup software_titles before the generated-column backfill
dnplkndll Jul 29, 2026
0a23e0b
docs(pg): record Phase 4 deploy — dedup, wrapper port, verification
dnplkndll Jul 29, 2026
2f7c1b7
fix(pg): harden dedup and backdated-port migrations per adversarial r…
dnplkndll Jul 29, 2026
c4d622d
test(pg): unit-cover TranslateError; refuse malformed duplicate keys
dnplkndll Jul 29, 2026
7acc335
chore(pg): shared MYSQL_TEST skip gate; accurate jobs clock comment
dnplkndll Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 8 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ The following terms were recently renamed. Use the new terms in conversation and

Go and API conventions (ctxerr error wrapping, error types, request/response structs, auth, slog, `new(expression)` pointers, endpoint registration) auto-load from `.claude/rules/` when you edit matching files — see `rules/fleet-go-backend.md`, `rules/fleet-api.md`, and `rules/fleet-database.md`. Reference example: `server/service/vulnerabilities.go`.

## Writing migrations

- Bulk UPDATE/DELETE steps in migrations must be batched (see
`incrementalMigrationStep` in `migrations/tables/`) — an unbatched
full-table statement holds locks for the whole run on large deployments.
- Avoid MySQL-only `UPDATE/DELETE ... LIMIT n`; use a keyed-subquery batch
(the PG driver rejects the LIMIT form).

## Before writing a fix

- Identify WHERE in the request lifecycle the problem manifests (creation vs team-addition vs sync vs query). Fix it there, not at the reproduction step.
Expand Down
92 changes: 92 additions & 0 deletions .github/actions/gitops/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: fleetctl-gitops
description: Runs fleetctl gitops to apply configuration to Fleet
# Schema: https://json.schemastore.org/github-action.json

# This action expects the following env vars to be set:
# - FLEET_URL: The URL of the Fleet server to apply configuration to.
# - FLEET_API_TOKEN: An API token for a Fleet GitOps user.
#
# Optional:
# - FLEET_GITOPS_DIR: The directory containing the GitOps config (default.yml,
# fleets/*.yml). Defaults to the current directory.
# - FLEET_CUSTOM_HEADERS: Comma-separated "Header:Value" pairs (e.g. a Cloudflare
# Access service token) sent on every request to the Fleet server.

inputs:
working-directory:
description: 'The working directory, which should be the root of the repository.'
default: './'
dry-run-only:
description: 'Whether to only run the fleetctl gitops commands in dry-run mode.'
default: 'false'
delete-other-fleets:
description: 'Whether to delete other fleets in Fleet which are not part of the gitops config.'
default: 'true'

runs:
using: "composite"
steps:
- name: Install fleetctl
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
FLEET_URL="${FLEET_URL%/}"

# Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated
# list of "Header:Value" pairs (e.g. a Cloudflare Access service token). Empty by default.
CURL_HEADER_ARGS=()
if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then
IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS"
for _header in "${_CUSTOM_HEADERS[@]}"; do
CURL_HEADER_ARGS+=(--header "$_header")
done
fi

FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" "${CURL_HEADER_ARGS[@]}" --fail --silent | jq --raw-output '.version')"
DEFAULT_FLEETCTL_VERSION="latest"

# Decide which fleetctl version to install:
# If the server returns a clean version (e.g. 4.74.0), use that.
# If the server returns a snapshot (e.g. 0.0.0-SNAPSHOT-xxxxx) or is empty, pin to DEFAULT_FLEETCTL_VERSION.
if [[ -z "$FLEET_VERSION" ]]; then
INSTALL_VERSION="$DEFAULT_FLEETCTL_VERSION"
elif [[ "$FLEET_VERSION" == 0.0.0-SNAPSHOT* ]]; then
INSTALL_VERSION="$DEFAULT_FLEETCTL_VERSION"
elif [[ "$FLEET_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
INSTALL_VERSION="$FLEET_VERSION"
else
# Strip anything after + (e.g. 4.81.0+foobar -> 4.81.0)
FLEET_VERSION="${FLEET_VERSION%%\+*}"
if [[ "$FLEET_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
INSTALL_VERSION="$FLEET_VERSION"
else
INSTALL_VERSION="$DEFAULT_FLEETCTL_VERSION"
fi
fi

echo "Installing fleetctl v$INSTALL_VERSION..."
npm install -g "fleetctl@$INSTALL_VERSION" || npm install -g fleetctl@latest

- name: Configure fleetctl
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
# Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated
# list of "Header:Value" pairs. fleetctl persists them and sends them on every request,
# so the gitops commands below use them too.
CUSTOM_HEADER_ARGS=()
if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then
IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS"
for _header in "${_CUSTOM_HEADERS[@]}"; do
CUSTOM_HEADER_ARGS+=(--custom-header "$_header")
done
fi
fleetctl config set --address "$FLEET_URL" --token "$FLEET_API_TOKEN" "${CUSTOM_HEADER_ARGS[@]}"

- name: Run fleetctl gitops commands
shell: bash
working-directory: ${{ inputs.working-directory }}
env:
FLEET_DRY_RUN_ONLY: ${{ inputs.dry-run-only }}
FLEET_DELETE_OTHER_FLEETS: ${{ inputs.delete-other-fleets }}
run: bash "$GITHUB_ACTION_PATH/gitops.sh"
59 changes: 59 additions & 0 deletions .github/actions/gitops/gitops.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash

# -e: Immediately exit if any command has a non-zero exit status.
# -x: Print all executed commands to the terminal.
# -u: Exit if an undefined variable is used.
# -o pipefail: Exit if any command in a pipeline fails.
set -exuo pipefail

FLEET_GITOPS_DIR="${FLEET_GITOPS_DIR:-.}"
FLEET_GLOBAL_FILE="${FLEET_GLOBAL_FILE:-$FLEET_GITOPS_DIR/default.yml}"
FLEETCTL="${FLEETCTL:-fleetctl}"
FLEET_DRY_RUN_ONLY="${FLEET_DRY_RUN_ONLY:-false}"
FLEET_DELETE_OTHER_FLEETS="${FLEET_DELETE_OTHER_FLEETS:-true}"

# Check for existence of the global file in case the script is used
# on repositories with fleet only yamls.
if [ -f "$FLEET_GLOBAL_FILE" ]; then
# Validate that global file contains org_settings
grep -Exq "^org_settings:.*" "$FLEET_GLOBAL_FILE"
else
FLEET_DELETE_OTHER_FLEETS=false
fi

# If you are using secrets to manage SSO metadata for Fleet SSO login or MDM SSO login, uncomment the below:

# FLEET_SSO_METADATA=$( sed '2,$s/^/ /' <<< "${FLEET_MDM_SSO_METADATA}")
# FLEET_MDM_SSO_METADATA=$( sed '2,$s/^/ /' <<< "${FLEET_MDM_SSO_METADATA}")

# Copy/pasting raw SSO metadata into GitHub secrets will result in malformed yaml.
# Adds spaces to all but the first line of metadata keeps the multiline string in bounds.

if compgen -G "$FLEET_GITOPS_DIR"/fleets/*.yml > /dev/null; then
# Validate that every fleet has a unique name.
# This is a limited check that assumes all fleet files contain the phrase: `name: <fleet_name>`
! perl -nle 'print $1 if /^name:\s*(.+)$/' "$FLEET_GITOPS_DIR"/fleets/*.yml | sort | uniq -d | grep . -cq
fi

args=()
if [ -f "$FLEET_GLOBAL_FILE" ]; then
args=(-f "$FLEET_GLOBAL_FILE")
fi

for fleet_file in "$FLEET_GITOPS_DIR"/fleets/*.yml; do
if [ -f "$fleet_file" ]; then
args+=(-f "$fleet_file")
fi
done
if [ "$FLEET_DELETE_OTHER_FLEETS" = true ]; then
args+=(--delete-other-fleets)
fi

# Dry run
$FLEETCTL gitops "${args[@]}" --dry-run
if [ "$FLEET_DRY_RUN_ONLY" = true ]; then
exit 0
fi

# Real run
$FLEETCTL gitops "${args[@]}"
4 changes: 4 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ permissions:
jobs:
dependency-review:
runs-on: ubuntu-latest
# actions/dependency-review-action requires GitHub Advanced Security on
# private repos. Skip on private mirrors (e.g. ledoent/fleet); upstream
# public fleetdm/fleet still runs the check.
if: ${{ !github.event.repository.private }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
Expand Down
11 changes: 1 addition & 10 deletions .github/workflows/dogfood-gitops.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,9 @@ jobs:
with:
persist-credentials: false

- name: Checkout GitOps repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
repository: fleetdm/fleet-gitops
ref: main
path: fleet-gitops
persist-credentials: false

- name: Apply latest configuration to Fleet
uses: ./fleet-gitops/.github/gitops-action-fleets
uses: ./.github/actions/gitops
with:
working-directory: ${{ github.workspace }}/fleet-gitops
dry-run-only: ${{ github.event_name == 'pull_request' && 'true' || 'false' }}
env:
FLEET_GITOPS_DIR: ${{ github.workspace }}/it-and-security
Expand Down
Loading
Loading