Compare commits

..

1 Commits

Author SHA1 Message Date
Regina Voloshin
9ea4ad6eb9 docs: Update releasing.md with handling a failed release
Signed-off-by: Regina Voloshin <regina.voloshin@codefresh.io>
2026-01-19 09:57:46 +02:00
613 changed files with 44996 additions and 71720 deletions

View File

@@ -4,7 +4,6 @@ module.exports = {
autodiscover: false,
allowPostUpgradeCommandTemplating: true,
allowedPostUpgradeCommands: ["make mockgen"],
binarySource: 'install',
extends: [
"github>argoproj/argo-cd//renovate-presets/commons.json5",
"github>argoproj/argo-cd//renovate-presets/custom-managers/shell.json5",

View File

@@ -1,15 +1,15 @@
{
"LABEL": {
"name": "title needs formatting",
"color": "EEEEEE"
},
"CHECKS": {
"prefixes": ["[Bot] docs: "],
"regexp": "^(refactor|feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
},
"MESSAGES": {
"success": "PR title is valid",
"failure": "PR title is invalid",
"notice": "PR Title needs to pass regex '^(refactor|feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
"LABEL": {
"name": "title needs formatting",
"color": "EEEEEE"
},
"CHECKS": {
"prefixes": ["[Bot] docs: "],
"regexp": "^(feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
},
"MESSAGES": {
"success": "PR title is valid",
"failure": "PR title is invalid",
"notice": "PR Title needs to pass regex '^(feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
}
}
}

View File

@@ -11,7 +11,6 @@
| release.yaml | Build images, cli-binaries, provenances, and post actions |
| scorecard.yaml | Generate scorecard for supply-chain security |
| update-snyk.yaml | Scheduled snyk reports |
| stale.yaml | Labels stale issues and PRs |
# Reusable workflows

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -74,7 +74,7 @@ jobs:
rsync -a --exclude=.git /home/runner/go/src/github.com/argoproj/argo-cd/ ../argo-cd
- name: Create pull request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
commit-message: "Bump major version to ${{ steps.get-target-version.outputs.TARGET_VERSION }}"
title: "Bump major version to ${{ steps.get-target-version.outputs.TARGET_VERSION }}"

View File

@@ -32,13 +32,13 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
with:
app-id: ${{ secrets.CHERRYPICK_APP_ID }}
private-key: ${{ secrets.CHERRYPICK_APP_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ steps.generate-token.outputs.token }}

View File

@@ -14,7 +14,7 @@ on:
env:
# Golang version to use across CI steps
# renovate: datasource=golang-version packageName=golang
GOLANG_VERSION: '1.26.0'
GOLANG_VERSION: '1.25.6'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -31,8 +31,8 @@ jobs:
frontend: ${{ steps.filter.outputs.frontend_any_changed }}
docs: ${{ steps.filter.outputs.docs_any_changed }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v47.0.4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
id: filter
with:
# Any file which is not under docs/, ui/ or is not a markdown file is counted as a backend file
@@ -55,7 +55,7 @@ jobs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Golang
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
@@ -75,13 +75,13 @@ jobs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Golang
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Restore go build cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -102,7 +102,7 @@ jobs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Golang
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
@@ -110,8 +110,8 @@ jobs:
- name: Run golangci-lint
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
# renovate: datasource=go packageName=github.com/golangci/golangci-lint/v2 versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
version: v2.10.1
# renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
version: v2.5.0
args: --verbose
test-go:
@@ -128,7 +128,7 @@ jobs:
- name: Create checkout directory
run: mkdir -p ~/go/src/github.com/argoproj
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Create symlink in GOPATH
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
- name: Setup Golang
@@ -152,7 +152,7 @@ jobs:
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Restore go build cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -192,7 +192,7 @@ jobs:
- name: Create checkout directory
run: mkdir -p ~/go/src/github.com/argoproj
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Create symlink in GOPATH
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
- name: Setup Golang
@@ -216,7 +216,7 @@ jobs:
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Restore go build cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -250,7 +250,7 @@ jobs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Golang
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
@@ -307,7 +307,7 @@ jobs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup NodeJS
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
@@ -315,7 +315,7 @@ jobs:
node-version: '22.9.0'
- name: Restore node dependency cache
id: cache-dependencies
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ui/node_modules
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
@@ -340,7 +340,7 @@ jobs:
shellcheck:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- run: |
sudo apt-get install shellcheck
shellcheck -e SC2059 -e SC2154 -e SC2034 -e SC2016 -e SC1091 $(find . -type f -name '*.sh' | grep -v './ui/node_modules') | tee sc.log
@@ -360,28 +360,32 @@ jobs:
codecov_secret: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Restore node dependency cache
id: cache-dependencies
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ui/node_modules
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
if: env.codecov_secret != ''
- name: Remove other node_modules directory
run: |
rm -rf ui/node_modules/argo-ui/node_modules
if: env.codecov_secret != ''
- name: Get e2e code coverage
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: e2e-code-coverage
path: e2e-code-coverage
if: env.codecov_secret != ''
- name: Get unit test code coverage
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: test-results
path: test-results
if: env.codecov_secret != ''
- name: combine-go-coverage
# We generate coverage reports for all Argo CD components, but only the applicationset-controller,
# app-controller, repo-server, and commit-server report contain coverage data. The other components currently
@@ -389,18 +393,18 @@ jobs:
# references to their coverage output directories.
run: |
go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller,e2e-code-coverage/commit-server -o test-results/full-coverage.out
if: env.codecov_secret != ''
- name: Upload code coverage information to codecov.io
# Only run when the workflow is for upstream (PR target or push is in argoproj/argo-cd).
if: github.repository == 'argoproj/argo-cd'
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
files: test-results/full-coverage.out
fail_ci_if_error: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
if: env.codecov_secret != ''
- name: Upload test results to Codecov
# Codecov uploads test results to Codecov.io on upstream master branch.
if: github.repository == 'argoproj/argo-cd' && github.ref == 'refs/heads/master' && github.event_name == 'push'
# Codecov uploads test results to Codecov.io on upstream master branch and on fork master branch if the token is configured.
if: env.codecov_secret != '' && github.ref == 'refs/heads/master' && github.event_name == 'push'
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
files: test-results/junit.xml
@@ -423,14 +427,14 @@ jobs:
# latest: true means that this version mush upload the coverage report to codecov.io
# We designate the latest version because we only collect code coverage for that version.
k3s:
- version: v1.35.0
latest: true
- version: v1.34.2
latest: false
latest: true
- version: v1.33.1
latest: false
- version: v1.32.1
latest: false
- version: v1.31.0
latest: false
needs:
- build-go
- changes
@@ -452,7 +456,7 @@ jobs:
swap-storage: false
tool-cache: false
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Golang
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
@@ -476,7 +480,7 @@ jobs:
sudo chmod go-r $HOME/.kube/config
kubectl version
- name: Restore go build cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -502,7 +506,7 @@ jobs:
git config --global user.email "john.doe@example.com"
- name: Pull Docker image required for tests
run: |
docker pull ghcr.io/dexidp/dex:v2.44.0
docker pull ghcr.io/dexidp/dex:v2.43.0
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:8.2.3-alpine
- name: Create target directory for binaries in the build-process

View File

@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
# Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087
- name: Setup Golang

View File

@@ -56,14 +56,14 @@ jobs:
image-digest: ${{ steps.image.outputs.digest }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.ref_type == 'tag'}}
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
if: ${{ github.ref_type != 'tag'}}
- name: Setup Golang
@@ -103,7 +103,7 @@ jobs:
echo 'EOF' >> $GITHUB_ENV
- name: Login to Quay.io
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: quay.io
username: ${{ secrets.quay_username }}
@@ -111,7 +111,7 @@ jobs:
if: ${{ inputs.quay_image_name && inputs.push }}
- name: Login to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ secrets.ghcr_username }}
@@ -119,7 +119,7 @@ jobs:
if: ${{ inputs.ghcr_image_name && inputs.push }}
- name: Login to dockerhub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.docker_username }}
password: ${{ secrets.docker_password }}
@@ -142,7 +142,7 @@ jobs:
- name: Build and push container image
id: image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 #v6.19.2
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
with:
context: .
platforms: ${{ inputs.platforms }}

View File

@@ -31,7 +31,7 @@ jobs:
ghcr_provenance_image: ${{ steps.image.outputs.ghcr_provenance_image }}
allow_ghcr_publish: ${{ steps.image.outputs.allow_ghcr_publish }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set image tag and names
run: |
@@ -86,7 +86,7 @@ jobs:
with:
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.26.0
go-version: 1.25.6
platforms: ${{ needs.set-vars.outputs.platforms }}
push: false
@@ -103,7 +103,7 @@ jobs:
ghcr_image_name: ${{ needs.set-vars.outputs.ghcr_image_name }}
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.26.0
go-version: 1.25.6
platforms: ${{ needs.set-vars.outputs.platforms }}
push: true
secrets:
@@ -140,7 +140,7 @@ jobs:
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- run: git clone "https://$TOKEN@github.com/argoproj/argoproj-deployments"
env:
TOKEN: ${{ secrets.TOKEN }}

View File

@@ -29,7 +29,7 @@ jobs:
IMAGE_REPOSITORY: ${{ vars.IMAGE_REPOSITORY || 'argocd' }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -70,7 +70,7 @@ jobs:
git stash pop
- name: Create pull request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
commit-message: "Bump version to ${{ inputs.TARGET_VERSION }}"
title: "Bump version to ${{ inputs.TARGET_VERSION }} on ${{ inputs.TARGET_BRANCH }} branch"

View File

@@ -11,7 +11,7 @@ permissions: {}
env:
# renovate: datasource=golang-version packageName=golang
GOLANG_VERSION: '1.26.0' # Note: go-version must also be set in job argocd-image.with.go-version
GOLANG_VERSION: '1.25.6' # Note: go-version must also be set in job argocd-image.with.go-version
jobs:
argocd-image:
@@ -26,7 +26,7 @@ jobs:
quay_image_name: ${{ needs.setup-variables.outputs.quay_image_name }}
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.26.0
go-version: 1.25.6
platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
push: true
secrets:
@@ -48,7 +48,7 @@ jobs:
allow_fork_release: ${{ steps.var.outputs.allow_fork_release }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -124,7 +124,7 @@ jobs:
hashes: ${{ steps.hash.outputs.hashes }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -159,7 +159,7 @@ jobs:
tool-cache: false
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
id: run-goreleaser
with:
version: latest
@@ -213,7 +213,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -300,7 +300,7 @@ jobs:
TAG_STABLE: ${{ needs.setup-variables.outputs.is_latest_release }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -344,7 +344,7 @@ jobs:
if: ${{ env.UPDATE_VERSION == 'true' }}
- name: Create PR to update VERSION on master branch
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
commit-message: Bump version in master
title: 'chore: Bump version in master'

View File

@@ -20,10 +20,17 @@ jobs:
private-key: ${{ secrets.RENOVATE_APP_PRIVATE_KEY }}
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1
# Some codegen commands require Go to be setup
- name: Setup Golang
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
# renovate: datasource=golang-version packageName=golang
go-version: 1.25.6
- name: Self-hosted Renovate
uses: renovatebot/github-action@8d75b92f43899d483728e9a8a7fd44238020f6e6 #46.1.2
uses: renovatebot/github-action@66387ab8c2464d575b933fa44e9e5a86b2822809 #44.2.4
with:
configurationFile: .github/configs/renovate-config.js
token: '${{ steps.get_token.outputs.token }}'

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

View File

@@ -1,33 +0,0 @@
name: "Label stale issues and PRs"
on:
schedule:
- cron: "0 0 * * *" #Runs midnight 12AM UTC
#Added Recommended permissions
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-24.04
steps:
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: >
This issue has been marked as stale because it has had no activity for 90 days. Please comment if this is still relevant.
stale-pr-message: >
This pull request has been marked as stale because it has had no activity for 90 days. Please comment if this is still relevant.
days-before-stale: 90
days-before-close: -1 # Auto-close diabled
exempt-issue-labels: >
bug, security, breaking/high, breaking/medium, breaking/low
# General configuration
operations-per-run: 200
remove-stale-when-updated: true #Remove stale label when issue/pr is updated

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Build reports

View File

@@ -22,7 +22,6 @@ linters:
- govet
- importas
- misspell
- modernize
- noctx
- perfsprint
- revive
@@ -122,13 +121,6 @@ linters:
- pkg: github.com/argoproj/argo-cd/v3/util/io
alias: utilio
modernize:
disable:
# Suggest replacing omitempty with omitzero for struct fields.
- omitzero
# Simplify code by using go1.26's new(expr). - generates lots of false positives.
- newexpr
nolintlint:
require-specific: true

View File

@@ -79,10 +79,10 @@ packages:
github.com/argoproj/argo-cd/v3/util/workloadidentity:
interfaces:
TokenProvider: {}
github.com/argoproj/argo-cd/gitops-engine/pkg/cache:
github.com/argoproj/gitops-engine/pkg/cache:
interfaces:
ClusterCache: {}
github.com/argoproj/argo-cd/gitops-engine/pkg/diff:
github.com/argoproj/gitops-engine/pkg/diff:
interfaces:
ServerSideDryRunner: {}
github.com/microsoft/azure-devops-go-api/azuredevops/v7/git:

View File

@@ -1,10 +1,10 @@
ARG BASE_IMAGE=docker.io/library/ubuntu:25.10@sha256:4a9232cc47bf99defcc8860ef6222c99773330367fcecbf21ba2edb0b810a31e
ARG BASE_IMAGE=docker.io/library/ubuntu:25.10@sha256:5922638447b1e3ba114332c896a2c7288c876bb94adec923d70d58a17d2fec5e
####################################################################################################
# Builder image
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image
# Also used as the image in CI jobs so needs all dependencies
####################################################################################################
FROM docker.io/library/golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5 AS builder
FROM docker.io/library/golang:1.25.6@sha256:fc24d3881a021e7b968a4610fc024fba749f98fe5c07d4f28e6cfa14dc65a84c AS builder
WORKDIR /tmp
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
unzip \
fcgiwrap \
git \
git-lfs \
make \
wget \
gcc \
@@ -28,8 +29,7 @@ COPY hack/install.sh hack/tool-versions.sh ./
COPY hack/installers installers
RUN ./install.sh helm && \
INSTALL_PATH=/usr/local/bin ./install.sh kustomize && \
./install.sh git-lfs
INSTALL_PATH=/usr/local/bin ./install.sh kustomize
####################################################################################################
# Argo CD Base - used as the base for both the release and dev argocd images
@@ -51,7 +51,7 @@ RUN groupadd -g $ARGOCD_USER_ID argocd && \
apt-get update && \
apt-get dist-upgrade -y && \
apt-get install --no-install-recommends -y \
git tini ca-certificates gpg gpg-agent tzdata connect-proxy openssh-client && \
git git-lfs tini ca-certificates gpg gpg-agent tzdata connect-proxy openssh-client && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
@@ -61,7 +61,6 @@ COPY hack/gpg-wrapper.sh \
/usr/local/bin/
COPY --from=builder /usr/local/bin/helm /usr/local/bin/helm
COPY --from=builder /usr/local/bin/kustomize /usr/local/bin/kustomize
COPY --from=builder /usr/local/bin/git-lfs /usr/local/bin/git-lfs
# keep uid_entrypoint.sh for backward compatibility
RUN ln -s /usr/local/bin/entrypoint.sh /usr/local/bin/uid_entrypoint.sh
@@ -80,12 +79,6 @@ RUN mkdir -p tls && \
ENV USER=argocd
# Disable gRPC service config lookups via DNS TXT records to prevent excessive
# DNS queries for _grpc_config.<hostname> which can cause timeouts in dual-stack
# environments. This can be overridden via argocd-cmd-params-cm ConfigMap.
# See https://github.com/argoproj/argo-cd/issues/24991
ENV GRPC_ENABLE_TXT_SERVICE_CONFIG=false
USER $ARGOCD_USER_ID
WORKDIR /home/argocd
@@ -110,7 +103,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP
####################################################################################################
# Argo CD Build stage which performs the actual build of Argo CD binaries
####################################################################################################
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5 AS argocd-build
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.25.6@sha256:fc24d3881a021e7b968a4610fc024fba749f98fe5c07d4f28e6cfa14dc65a84c AS argocd-build
WORKDIR /go/src/github.com/argoproj/argo-cd

View File

@@ -1,4 +1,4 @@
FROM docker.io/library/golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5
FROM docker.io/library/golang:1.25.6@sha256:fc24d3881a021e7b968a4610fc024fba749f98fe5c07d4f28e6cfa14dc65a84c
ENV DEBIAN_FRONTEND=noninteractive
@@ -11,6 +11,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
unzip \
fcgiwrap \
git \
git-lfs \
make \
wget \
gcc \
@@ -27,8 +28,7 @@ COPY hack/install.sh hack/tool-versions.sh ./
COPY hack/installers installers
RUN ./install.sh helm && \
INSTALL_PATH=/usr/local/bin ./install.sh kustomize && \
./install.sh git-lfs
INSTALL_PATH=/usr/local/bin ./install.sh kustomize
COPY hack/gpg-wrapper.sh \
hack/git-verify-wrapper.sh \

View File

@@ -18,14 +18,14 @@ This document lists the maintainers of the Argo CD project.
| Dan Garfield | [todaywasawesome](https://github.com/todaywasawesome) | Approver(docs) | [Octopus Deploy](https://octopus.com/) |
| Alexandre Gaudreault | [agaudreault](https://github.com/agaudreault) | Approver | [Intuit](https://www.github.com/intuit/) |
| Christian Hernandez | [christianh814](https://github.com/christianh814) | Reviewer(docs) | [Akuity](https://akuity.io/) |
| Peter Jiang | [pjiang-dev](https://github.com/pjiang-dev) | Approver(docs) | [Intuit](https://www.intuit.com/) |
| Peter Jiang | [pjiang](https://github.com/pjiang) | Reviewer | [Intuit](https://www.intuit.com/) |
| Andrii Korotkov | [andrii-korotkov](https://github.com/andrii-korotkov) | Reviewer | [Verkada](https://www.verkada.com/) |
| Pasha Kostohrys | [pasha-codefresh](https://github.com/pasha-codefresh) | Approver | [Codefresh](https://www.github.com/codefresh/) |
| Nitish Kumar | [nitishfy](https://github.com/nitishfy) | Approver(cli,docs) | [Akuity](https://akuity.io/) |
| Justin Marquis | [34fathombelow](https://github.com/34fathombelow) | Approver(docs/ci) | [Akuity](https://akuity.io/) |
| Alexander Matyushentsev | [alexmt](https://github.com/alexmt) | Lead | [Akuity](https://akuity.io/) |
| Nicholas Morey | [morey-tech](https://github.com/morey-tech) | Reviewer(docs) | [Akuity](https://akuity.io/) |
| Papapetrou Patroklos | [ppapapetrou76](https://github.com/ppapapetrou76) | Approver(docs,cli) | [Octopus Deploy](https://octopus.com/) |
| Papapetrou Patroklos | [ppapapetrou76](https://github.com/ppapapetrou76) | Reviewer | [Octopus Deploy](https://octopus.com/) |
| Blake Pettersson | [blakepettersson](https://github.com/blakepettersson) | Approver | [Akuity](https://akuity.io/) |
| Ishita Sequeira | [ishitasequeira](https://github.com/ishitasequeira) | Approver | [Red Hat](https://redhat.com/) |
| Ashutosh Singh | [ashutosh16](https://github.com/ashutosh16) | Approver(docs) | [Intuit](https://www.github.com/intuit/) |
@@ -37,7 +37,3 @@ This document lists the maintainers of the Argo CD project.
| Regina Voloshin | [reggie-k](https://github.com/reggie-k) | Approver | [Octopus Deploy](https://octopus.com/) |
| Hong Wang | [wanghong230](https://github.com/wanghong230) | Reviewer | [Akuity](https://akuity.io/) |
| Jonathan West | [jgwest](https://github.com/jgwest) | Approver | [Red Hat](https://redhat.com/) |
| Jaewoo Choi | [choejwoo](https://github.com/choejwoo) | Reviewer | [Hyundai-Autoever](https://www.hyundai-autoever.com/eng/) |
| Alexy Mantha | [alexymantha](https://github.com/alexymantha) | Reviewer | GoTo |
| Kanika Rana | [ranakan19](https://github.com/ranakan19) | Reviewer | [Red Hat](https://redhat.com/) |
| Jonathan Winters | [jwinters01](https://github.com/jwinters01) | Reviewer | [Intuit](https://www.github.com/intuit/) |

View File

@@ -353,7 +353,7 @@ controller:
build-ui:
DOCKER_BUILDKIT=1 $(DOCKER) build -t argocd-ui --platform=$(TARGET_ARCH) --target argocd-ui .
find ./ui/dist -type f -not -name gitkeep -delete
$(DOCKER) run -u $(CONTAINER_UID):$(CONTAINER_GID) -v ${CURRENT_DIR}/ui/dist/app:/tmp/app --rm -t argocd-ui sh -c 'cp -r ./dist/app/* /tmp/app/'
$(DOCKER) run -v ${CURRENT_DIR}/ui/dist/app:/tmp/app --rm -t argocd-ui sh -c 'cp -r ./dist/app/* /tmp/app/'
.PHONY: image
ifeq ($(DEV_IMAGE), true)
@@ -444,23 +444,17 @@ test: test-tools-image
# Run all unit tests (local version)
.PHONY: test-local
test-local: test-gitops-engine
# run if TEST_MODULE is empty or does not point to gitops-engine tests
ifneq ($(if $(TEST_MODULE),,ALL)$(filter-out github.com/argoproj/argo-cd/gitops-engine% ./gitops-engine%,$(TEST_MODULE)),)
if test "$(TEST_MODULE)" = ""; then \
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES=`go list ./... | grep -v 'test/e2e'` ./hack/test.sh -args -test.gocoverdir="$(PWD)/test-results"; \
else \
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES="$(TEST_MODULE)" ./hack/test.sh -args -test.gocoverdir="$(PWD)/test-results" "$(TEST_MODULE)"; \
fi
endif
# Run gitops-engine unit tests
.PHONY: test-gitops-engine
test-gitops-engine:
# run if TEST_MODULE is empty or points to gitops-engine tests
ifneq ($(if $(TEST_MODULE),,ALL)$(filter github.com/argoproj/argo-cd/gitops-engine% ./gitops-engine%,$(TEST_MODULE)),)
mkdir -p $(PWD)/test-results
cd gitops-engine && go test -race -cover ./... -args -test.gocoverdir="$(PWD)/test-results"
endif
.PHONY: test-race
test-race: test-tools-image

View File

@@ -60,7 +60,7 @@ k8s_yaml(kustomize('manifests/dev-tilt'))
# build dev image
docker_build_with_restart(
'quay.io/argoproj/argocd:latest',
'argocd',
context='.',
dockerfile='Dockerfile.tilt',
entrypoint=[

View File

@@ -7,7 +7,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [100ms](https://www.100ms.ai/)
1. [127Labs](https://127labs.com/)
1. [3Rein](https://3reinmedia.com/)
1. [3Rein](https://www.3rein.com/)
1. [42 School](https://42.fr/)
1. [4data](https://4data.ch/)
1. [7shifts](https://www.7shifts.com/)
@@ -31,8 +31,8 @@ Currently, the following organizations are **officially** using Argo CD:
1. [ANSTO - Australian Synchrotron](https://www.synchrotron.org.au/)
1. [Ant Group](https://www.antgroup.com/)
1. [AppDirect](https://www.appdirect.com)
1. [Arcadia](https://arcadia.io/)
1. [Arctiq Inc.](https://arctiq.com/)
1. [Arcadia](https://www.arcadia.io)
1. [Arctiq Inc.](https://www.arctiq.ca)
1. [Artemis Health by Nomi Health](https://www.artemishealth.com/)
1. [Arturia](https://www.arturia.com)
1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/)
@@ -147,14 +147,14 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Getir](https://getir.com)
1. [GetYourGuide](https://www.getyourguide.com/)
1. [Gitpod](https://www.gitpod.io)
1. [Gllue](https://www.gllue.com/)
1. [Gllue](https://gllue.com)
1. [gloat](https://gloat.com/)
1. [GLOBIS](https://globis.com)
1. [Glovo](https://www.glovoapp.com)
1. [GlueOps](https://glueops.dev)
1. [GMETRI](https://gmetri.com/)
1. [Gojek](https://www.gojek.io/)
1. [GoTo Financial](https://www.gotocompany.com/en/products/goto-financial)
1. [GoTo Financial](https://gotofinancial.com/)
1. [GoTo](https://www.goto.com/)
1. [Greenpass](https://www.greenpass.com.br/)
1. [Gridfuse](https://gridfuse.com/)
@@ -165,7 +165,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Healy](https://www.healyworld.net)
1. [Helio](https://helio.exchange)
1. [hetao101](https://www.hetao101.com/)
1. [Hetki](https://hetki.io/)
1. [Hetki](https://hetki.ai)
1. [hipages](https://hipages.com.au/)
1. [Hiya](https://hiya.com)
1. [Honestbank](https://honestbank.com)
@@ -177,8 +177,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Icelandair](https://www.icelandair.com)
1. [IFS](https://www.ifs.com)
1. [IITS-Consulting](https://iits-consulting.de)
1. [IllumiDesk](https://illumichat.com/)
1. [Imagine Learning](https://www.imaginelearning.com/)
1. [IllumiDesk](https://www.illumidesk.com)
1. [imaware](https://imaware.health)
1. [Indeed](https://indeed.com)
1. [Index Exchange](https://www.indexexchange.com/)
@@ -213,7 +212,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [LeFigaro](https://www.lefigaro.fr/)
1. [Lely](https://www.lely.com/)
1. [LexisNexis](https://www.lexisnexis.com/)
1. [Lian Chu Securities](https://www.lczq.com/)
1. [Lian Chu Securities](https://lczq.com)
1. [Liatrio](https://www.liatrio.com)
1. [Lightricks](https://www.lightricks.com/)
1. [Loom](https://www.loom.com/)
@@ -246,7 +245,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [MTN Group](https://www.mtn.com/)
1. [Municipality of The Hague](https://www.denhaag.nl/)
1. [My Job Glasses](https://myjobglasses.com)
1. [Natura &Co](https://ri.natura.com.br/)
1. [Natura &Co](https://naturaeco.com/)
1. [Netease Cloud Music](https://music.163.com/)
1. [Nethopper](https://nethopper.io)
1. [New Relic](https://newrelic.com/)
@@ -277,7 +276,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Orbital Insight](https://orbitalinsight.com/)
1. [Oscar Health Insurance](https://hioscar.com/)
1. [Outpost24](https://outpost24.com/)
1. [p3r](https://persona.atlus.com/p3r/)
1. [p3r](https://www.p3r.one/)
1. [Packlink](https://www.packlink.com/)
1. [PagerDuty](https://www.pagerduty.com/)
1. [Pandosearch](https://www.pandosearch.com/en/home)
@@ -331,7 +330,6 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Salad Technologies](https://salad.com/)
1. [Saloodo! GmbH](https://www.saloodo.com)
1. [Sap Labs](http://sap.com)
1. [SAP Signavio](https://www.signavio.com)
1. [Sauce Labs](https://saucelabs.com/)
1. [Schneider Electric](https://www.se.com)
1. [Schwarz IT](https://jobs.schwarz/it-mission)
@@ -419,18 +417,18 @@ Currently, the following organizations are **officially** using Argo CD:
1. [VSHN - The DevOps Company](https://vshn.ch/)
1. [Wakacje.pl](https://www.wakacje.pl/)
1. [Walkbase](https://www.walkbase.com/)
1. [Webstores](https://www.friday.nl/)
1. [Webstores](https://www.webstores.nl)
1. [Wehkamp](https://www.wehkamp.nl/)
1. [WeMaintain](https://www.wemaintain.com/)
1. [WeMo Scooter](https://www.wemoscooter.com/)
1. [Whitehat Berlin](https://whitehat.berlin) by Guido Maria Serra +Fenaroli
1. [Witick](https://www.witik.io/en/)
1. [Witick](https://witick.io/)
1. [Wolffun Game](https://www.wolffungame.com/)
1. [WooliesX](https://wooliesx.com.au/)
1. [Woolworths Group](https://www.woolworthsgroup.com.au/)
1. [WSpot](https://www.wspot.com.br/)
1. [X3M ads](https://x3mads.com)
1. [Yieldlab](https://virtualminds.com/)
1. [Yieldlab](https://www.yieldlab.de/)
1. [Youverify](https://youverify.co/)
1. [Yubo](https://www.yubo.live/)
1. [Yuno](https://y.uno/)

View File

@@ -20,7 +20,6 @@ import (
"fmt"
"reflect"
"runtime/debug"
"slices"
"sort"
"strconv"
"strings"
@@ -38,6 +37,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/retry"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -47,7 +47,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/argo-cd/v3/applicationset/controllers/template"
"github.com/argoproj/argo-cd/v3/applicationset/generators"
@@ -243,6 +243,11 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, fmt.Errorf("failed to get current applications for application set: %w", err)
}
err = r.updateResourcesStatus(ctx, logCtx, &applicationSetInfo, currentApplications)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to get update resources status for application set: %w", err)
}
// appSyncMap tracks which apps will be synced during this reconciliation.
appSyncMap := map[string]bool{}
@@ -366,16 +371,6 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}
}
// Update resources status after create/update/delete so it reflects the actual cluster state.
currentApplications, err = r.getCurrentApplications(ctx, applicationSetInfo)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to get current applications for application set: %w", err)
}
err = r.updateResourcesStatus(ctx, logCtx, &applicationSetInfo, currentApplications)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to update resources status for application set: %w", err)
}
if applicationSetInfo.RefreshRequired() {
delete(applicationSetInfo.Annotations, common.AnnotationApplicationSetRefresh)
err := r.Update(ctx, &applicationSetInfo)
@@ -1051,10 +1046,12 @@ func labelMatchedExpression(logCtx *log.Entry, val string, matchExpression argov
// if operator == NotIn, default to true
valueMatched := matchExpression.Operator == "NotIn"
if slices.Contains(matchExpression.Values, val) {
// first "In" match returns true
// first "NotIn" match returns false
return matchExpression.Operator == "In"
for _, value := range matchExpression.Values {
if val == value {
// first "In" match returns true
// first "NotIn" match returns false
return matchExpression.Operator == "In"
}
}
return valueMatched
}
@@ -1587,7 +1584,7 @@ func (r *ApplicationSetReconciler) syncDesiredApplications(logCtx *log.Entry, ap
// ensure that Applications generated with RollingSync do not have an automated sync policy, since the AppSet controller will handle triggering the sync operation instead
if desiredApplications[i].Spec.SyncPolicy != nil && desiredApplications[i].Spec.SyncPolicy.IsAutomatedSyncEnabled() {
pruneEnabled = desiredApplications[i].Spec.SyncPolicy.Automated.Prune
desiredApplications[i].Spec.SyncPolicy.Automated.Enabled = new(false)
desiredApplications[i].Spec.SyncPolicy.Automated.Enabled = ptr.To(false)
}
appSetStatusPending := false

View File

@@ -28,8 +28,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/event"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/argoproj/argo-cd/v3/applicationset/generators"
"github.com/argoproj/argo-cd/v3/applicationset/generators/mocks"
@@ -2950,112 +2950,6 @@ func TestUpdatePerformedWithSyncPolicySync(t *testing.T) {
assert.Equal(t, map[string]string{"label-key": "label-value"}, app.Labels)
}
// TestReconcilePopulatesResourcesStatusOnFirstRun verifies that status.resources and status.resourcesCount
// are populated after the first reconcile, when applications are created.
func TestReconcilePopulatesResourcesStatusOnFirstRun(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = corev1.AddToScheme(scheme)
require.NoError(t, err)
defaultProject := v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"},
Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://good-cluster"}}},
}
applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicySync
appSet := v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "argocd",
},
Spec: v1alpha1.ApplicationSetSpec{
Generators: []v1alpha1.ApplicationSetGenerator{
{
List: &v1alpha1.ListGenerator{
Elements: []apiextensionsv1.JSON{{
Raw: []byte(`{"cluster": "good-cluster","url": "https://good-cluster"}`),
}},
},
},
},
SyncPolicy: &v1alpha1.ApplicationSetSyncPolicy{
ApplicationsSync: &applicationsSyncPolicy,
},
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{
Name: "{{cluster}}",
Namespace: "argocd",
},
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"},
Project: "default",
Destination: v1alpha1.ApplicationDestination{Server: "{{url}}"},
},
},
},
}
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster",
Namespace: "argocd",
Labels: map[string]string{
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
},
},
Data: map[string][]byte{
"name": []byte("good-cluster"),
"server": []byte("https://good-cluster"),
"config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"),
},
}
kubeclientset := getDefaultTestClientSet(secret)
client := fake.NewClientBuilder().
WithScheme(scheme).
WithObjects(&appSet, &defaultProject, secret).
WithStatusSubresource(&appSet).
WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).
Build()
metrics := appsetmetrics.NewFakeAppsetMetrics()
argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset)
clusterInformer, err := settings.NewClusterInformer(kubeclientset, "argocd")
require.NoError(t, err)
defer startAndSyncInformer(t, clusterInformer)()
r := ApplicationSetReconciler{
Client: client,
Scheme: scheme,
Renderer: &utils.Render{},
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{"List": generators.NewListGenerator()},
ArgoDB: argodb,
ArgoCDNamespace: "argocd",
KubeClientset: kubeclientset,
Policy: v1alpha1.ApplicationsSyncPolicySync,
Metrics: metrics,
ClusterInformer: clusterInformer,
}
req := ctrl.Request{
NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "name"},
}
_, err = r.Reconcile(t.Context(), req)
require.NoError(t, err)
var retrievedAppSet v1alpha1.ApplicationSet
err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedAppSet)
require.NoError(t, err)
assert.Len(t, retrievedAppSet.Status.Resources, 1, "status.resources should have 1 item after first reconcile")
assert.Equal(t, int64(1), retrievedAppSet.Status.ResourcesCount, "status.resourcesCount should be 1 after first reconcile")
assert.Equal(t, "good-cluster", retrievedAppSet.Status.Resources[0].Name)
}
func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) {
applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateOnly
@@ -4758,7 +4652,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
newDefaultAppSet := func(stepsCount int, status []v1alpha1.ApplicationSetApplicationStatus) v1alpha1.ApplicationSet {
steps := []v1alpha1.ApplicationSetRolloutStep{}
for range stepsCount {
for i := 0; i < stepsCount; i++ {
steps = append(steps, v1alpha1.ApplicationSetRolloutStep{MatchExpressions: []v1alpha1.ApplicationMatchExpression{}})
}
return v1alpha1.ApplicationSet{
@@ -6471,7 +6365,7 @@ func TestUpdateResourceStatus(t *testing.T) {
func generateNAppResourceStatuses(n int) []v1alpha1.ResourceStatus {
var r []v1alpha1.ResourceStatus
for i := range n {
for i := 0; i < n; i++ {
r = append(r, v1alpha1.ResourceStatus{
Name: "app" + strconv.Itoa(i),
Status: v1alpha1.SyncStatusCodeSynced,
@@ -6486,7 +6380,7 @@ func generateNAppResourceStatuses(n int) []v1alpha1.ResourceStatus {
func generateNHealthyApps(n int) []v1alpha1.Application {
var r []v1alpha1.Application
for i := range n {
for i := 0; i < n; i++ {
r = append(r, v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app" + strconv.Itoa(i),

View File

@@ -3,7 +3,6 @@ package generators
import (
"context"
"fmt"
"maps"
"path"
"sort"
"strconv"
@@ -169,7 +168,9 @@ func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1al
if err != nil {
return nil, err
}
maps.Copy(fileContentMap, retrievedFiles)
for absPath, content := range retrievedFiles {
fileContentMap[absPath] = content
}
}
// Now remove files matching any exclude pattern
@@ -241,7 +242,9 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent []
params := map[string]any{}
if useGoTemplate {
maps.Copy(params, objectFound)
for k, v := range objectFound {
params[k] = v
}
paramPath := map[string]any{}

View File

@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"github.com/argoproj/argo-cd/v3/applicationset/services/mocks"
@@ -2422,7 +2423,7 @@ func TestGitGenerator_GenerateParams(t *testing.T) {
},
},
expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
expectedProject: new("project"),
expectedProject: ptr.To("project"),
expectedError: nil,
},
{
@@ -2456,7 +2457,7 @@ func TestGitGenerator_GenerateParams(t *testing.T) {
},
},
expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
expectedProject: new(""),
expectedProject: ptr.To(""),
expectedError: nil,
},
}

View File

@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"maps"
"strconv"
"strings"
"time"
@@ -116,7 +115,9 @@ func (g *PluginGenerator) generateParams(appSetGenerator *argoprojiov1alpha1.App
params := map[string]any{}
if useGoTemplate {
maps.Copy(params, objectFound)
for k, v := range objectFound {
params[k] = v
}
} else {
flat, err := flatten.Flatten(objectFound, "", flatten.DotStyle)
if err != nil {

View File

@@ -96,9 +96,15 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
var shortSHALength int
var shortSHALength7 int
for _, pull := range pulls {
shortSHALength = min(len(pull.HeadSHA), 8)
shortSHALength = 8
if len(pull.HeadSHA) < 8 {
shortSHALength = len(pull.HeadSHA)
}
shortSHALength7 = min(len(pull.HeadSHA), 7)
shortSHALength7 = 7
if len(pull.HeadSHA) < 7 {
shortSHALength7 = len(pull.HeadSHA)
}
paramMap := map[string]any{
"number": strconv.FormatInt(pull.Number, 10),

View File

@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"slices"
"strings"
"time"
@@ -106,8 +105,10 @@ func ScmProviderAllowed(applicationSetInfo *argoprojiov1alpha1.ApplicationSet, g
return nil
}
if slices.Contains(allowedScmProviders, url) {
return nil
for _, allowedScmProvider := range allowedScmProviders {
if url == allowedScmProvider {
return nil
}
}
log.WithFields(log.Fields{
@@ -243,9 +244,15 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
var shortSHALength int
var shortSHALength7 int
for _, repo := range repos {
shortSHALength = min(len(repo.SHA), 8)
shortSHALength = 8
if len(repo.SHA) < 8 {
shortSHALength = len(repo.SHA)
}
shortSHALength7 = min(len(repo.SHA), 7)
shortSHALength7 = 7
if len(repo.SHA) < 7 {
shortSHALength7 = len(repo.SHA)
}
params := map[string]any{
"organization": repo.Organization,

View File

@@ -2,7 +2,6 @@ package generators
import (
"fmt"
"maps"
)
func appendTemplatedValues(values map[string]string, params map[string]any, useGoTemplate bool, goTemplateOptions []string) error {
@@ -27,7 +26,9 @@ func appendTemplatedValues(values map[string]string, params map[string]any, useG
}
}
maps.Copy(params, tmp)
for key, value := range tmp {
params[key] = value
}
return nil
}

View File

@@ -151,9 +151,9 @@ spec:
func newFakeAppsets(fakeAppsetYAML string) []argoappv1.ApplicationSet {
var results []argoappv1.ApplicationSet
appsetRawYamls := strings.SplitSeq(fakeAppsetYAML, "---")
appsetRawYamls := strings.Split(fakeAppsetYAML, "---")
for appsetRawYaml := range appsetRawYamls {
for _, appsetRawYaml := range appsetRawYamls {
var appset argoappv1.ApplicationSet
err := yaml.Unmarshal([]byte(appsetRawYaml), &appset)
if err != nil {

View File

@@ -3,7 +3,6 @@ package pull_request
import (
"context"
"fmt"
"slices"
"strings"
"github.com/microsoft/azure-devops-go-api/azuredevops/v7"
@@ -137,7 +136,13 @@ func convertLabels(tags *[]core.WebApiTagDefinition) []string {
// containAzureDevOpsLabels returns true if gotLabels contains expectedLabels
func containAzureDevOpsLabels(expectedLabels []string, gotLabels []string) bool {
for _, expected := range expectedLabels {
found := slices.Contains(gotLabels, expected)
found := false
for _, got := range gotLabels {
if expected == got {
found = true
break
}
}
if !found {
return false
}

View File

@@ -15,6 +15,26 @@ import (
"github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/mocks"
)
func createBoolPtr(x bool) *bool {
return &x
}
func createStringPtr(x string) *string {
return &x
}
func createIntPtr(x int) *int {
return &x
}
func createLabelsPtr(x []core.WebApiTagDefinition) *[]core.WebApiTagDefinition {
return &x
}
func createUniqueNamePtr(x string) *string {
return &x
}
func TestListPullRequest(t *testing.T) {
teamProject := "myorg_project"
repoName := "myorg_project_repo"
@@ -26,19 +46,19 @@ func TestListPullRequest(t *testing.T) {
pullRequestMock := []git.GitPullRequest{
{
PullRequestId: new(prID),
Title: new(prTitle),
SourceRefName: new("refs/heads/feature-branch"),
TargetRefName: new("refs/heads/main"),
PullRequestId: createIntPtr(prID),
Title: createStringPtr(prTitle),
SourceRefName: createStringPtr("refs/heads/feature-branch"),
TargetRefName: createStringPtr("refs/heads/main"),
LastMergeSourceCommit: &git.GitCommitRef{
CommitId: new(prHeadSha),
CommitId: createStringPtr(prHeadSha),
},
Labels: &[]core.WebApiTagDefinition{},
Repository: &git.GitRepository{
Name: new(repoName),
Name: createStringPtr(repoName),
},
CreatedBy: &webapi.IdentityRef{
UniqueName: new(uniqueName + "@example.com"),
UniqueName: createUniqueNamePtr(uniqueName + "@example.com"),
},
},
}
@@ -79,27 +99,27 @@ func TestConvertLabes(t *testing.T) {
}{
{
name: "empty labels",
gotLabels: &[]core.WebApiTagDefinition{},
gotLabels: createLabelsPtr([]core.WebApiTagDefinition{}),
expectedLabels: []string{},
},
{
name: "nil labels",
gotLabels: nil,
gotLabels: createLabelsPtr(nil),
expectedLabels: []string{},
},
{
name: "one label",
gotLabels: &[]core.WebApiTagDefinition{
{Name: new("label1"), Active: new(true)},
},
gotLabels: createLabelsPtr([]core.WebApiTagDefinition{
{Name: createStringPtr("label1"), Active: createBoolPtr(true)},
}),
expectedLabels: []string{"label1"},
},
{
name: "two label",
gotLabels: &[]core.WebApiTagDefinition{
{Name: new("label1"), Active: new(true)},
{Name: new("label2"), Active: new(true)},
},
gotLabels: createLabelsPtr([]core.WebApiTagDefinition{
{Name: createStringPtr("label1"), Active: createBoolPtr(true)},
{Name: createStringPtr("label2"), Active: createBoolPtr(true)},
}),
expectedLabels: []string{"label1", "label2"},
},
}
@@ -196,7 +216,7 @@ func TestBuildURL(t *testing.T) {
func TestAzureDevOpsListReturnsRepositoryNotFoundError(t *testing.T) {
args := git.GetPullRequestsByProjectArgs{
Project: new("nonexistent"),
Project: createStringPtr("nonexistent"),
SearchCriteria: &git.GitPullRequestSearchCriteria{},
}

View File

@@ -268,6 +268,7 @@ func TestListPullRequestTLS(t *testing.T) {
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defaultHandler(t)(w, r)

View File

@@ -83,7 +83,7 @@ func (g *GiteaService) List(ctx context.Context) ([]*PullRequest, error) {
// containLabels returns true if gotLabels contains expectedLabels
func giteaContainLabels(expectedLabels []string, gotLabels []*gitea.Label) bool {
gotLabelNamesMap := make(map[string]bool)
for i := range gotLabels {
for i := 0; i < len(gotLabels); i++ {
gotLabelNamesMap[gotLabels[i].Name] = true
}
for _, expected := range expectedLabels {

View File

@@ -10,6 +10,10 @@ import (
"github.com/stretchr/testify/require"
)
func toPtr(s string) *string {
return &s
}
func TestContainLabels(t *testing.T) {
cases := []struct {
Name string
@@ -21,9 +25,9 @@ func TestContainLabels(t *testing.T) {
Name: "Match labels",
Labels: []string{"label1", "label2"},
PullLabels: []*github.Label{
{Name: new("label1")},
{Name: new("label2")},
{Name: new("label3")},
{Name: toPtr("label1")},
{Name: toPtr("label2")},
{Name: toPtr("label3")},
},
Expect: true,
},
@@ -31,9 +35,9 @@ func TestContainLabels(t *testing.T) {
Name: "Not match labels",
Labels: []string{"label1", "label4"},
PullLabels: []*github.Label{
{Name: new("label1")},
{Name: new("label2")},
{Name: new("label3")},
{Name: toPtr("label1")},
{Name: toPtr("label2")},
{Name: toPtr("label3")},
},
Expect: false,
},
@@ -41,9 +45,9 @@ func TestContainLabels(t *testing.T) {
Name: "No specify",
Labels: []string{},
PullLabels: []*github.Label{
{Name: new("label1")},
{Name: new("label2")},
{Name: new("label3")},
{Name: toPtr("label1")},
{Name: toPtr("label2")},
{Name: toPtr("label3")},
},
Expect: true,
},
@@ -66,9 +70,9 @@ func TestGetGitHubPRLabelNames(t *testing.T) {
{
Name: "PR has labels",
PullLabels: []*github.Label{
{Name: new("label1")},
{Name: new("label2")},
{Name: new("label3")},
{Name: toPtr("label1")},
{Name: toPtr("label2")},
{Name: toPtr("label3")},
},
ExpectedResult: []string{"label1", "label2", "label3"},
},

View File

@@ -158,6 +158,7 @@ func TestListWithStateTLS(t *testing.T) {
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
writeMRListResponse(t, w)

View File

@@ -9,6 +9,10 @@ import (
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
)
func strp(s string) *string {
return &s
}
func TestFilterBranchMatchBadRegexp(t *testing.T) {
provider, _ := NewFakeService(
t.Context(),
@@ -26,7 +30,7 @@ func TestFilterBranchMatchBadRegexp(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
BranchMatch: new("("),
BranchMatch: strp("("),
},
}
_, err := ListPullRequests(t.Context(), provider, filters)
@@ -74,7 +78,7 @@ func TestFilterBranchMatch(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
BranchMatch: new("w"),
BranchMatch: strp("w"),
},
}
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
@@ -124,7 +128,7 @@ func TestFilterTargetBranchMatch(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
TargetBranchMatch: new("1"),
TargetBranchMatch: strp("1"),
},
}
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
@@ -174,7 +178,7 @@ func TestFilterTitleMatch(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
TitleMatch: new("\\[filter]"),
TitleMatch: strp("\\[filter]"),
},
}
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
@@ -224,10 +228,10 @@ func TestMultiFilterOrWithTitle(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
TitleMatch: new("\\[filter]"),
TitleMatch: strp("\\[filter]"),
},
{
TitleMatch: new("- filter"),
TitleMatch: strp("- filter"),
},
}
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
@@ -278,10 +282,10 @@ func TestMultiFilterOr(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
BranchMatch: new("w"),
BranchMatch: strp("w"),
},
{
BranchMatch: new("r"),
BranchMatch: strp("r"),
},
}
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
@@ -341,19 +345,19 @@ func TestMultiFilterOrWithTargetBranchFilterOrWithTitleFilter(t *testing.T) {
)
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{
{
BranchMatch: new("w"),
TargetBranchMatch: new("1"),
BranchMatch: strp("w"),
TargetBranchMatch: strp("1"),
},
{
BranchMatch: new("r"),
TargetBranchMatch: new("3"),
BranchMatch: strp("r"),
TargetBranchMatch: strp("3"),
},
{
TitleMatch: new("two"),
TitleMatch: strp("two"),
},
{
BranchMatch: new("five"),
TitleMatch: new("PR title is different than branch name"),
BranchMatch: strp("five"),
TitleMatch: strp("PR title is different than branch name"),
},
}
pullRequests, err := ListPullRequests(t.Context(), provider, filters)

View File

@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"k8s.io/utils/ptr"
"github.com/microsoft/azure-devops-go-api/azuredevops/v7"
azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git"
@@ -17,6 +18,10 @@ import (
"github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/mocks"
)
func s(input string) *string {
return ptr.To(input)
}
func TestAzureDevopsRepoHasPath(t *testing.T) {
organization := "myorg"
teamProject := "myorg_project"
@@ -46,12 +51,12 @@ func TestAzureDevopsRepoHasPath(t *testing.T) {
{
name: "RepoHasPath when no path found returns false",
pathFound: false,
azureDevopsError: azuredevops.WrappedError{TypeKey: new(AzureDevOpsErrorsTypeKeyValues.GitItemNotFound)},
azureDevopsError: azuredevops.WrappedError{TypeKey: s(AzureDevOpsErrorsTypeKeyValues.GitItemNotFound)},
},
{
name: "RepoHasPath when unknown Azure DevOps WrappedError occurs returns error",
pathFound: false,
azureDevopsError: azuredevops.WrappedError{TypeKey: new("OtherAzureDevopsException")},
azureDevopsError: azuredevops.WrappedError{TypeKey: s("OtherAzureDevopsException")},
returnError: true,
errorMessage: "failed to check for path existence",
},
@@ -119,12 +124,12 @@ func TestGetDefaultBranchOnDisabledRepo(t *testing.T) {
}{
{
name: "azure devops error when disabled repo causes empty return value",
azureDevOpsError: azuredevops.WrappedError{TypeKey: new(AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound)},
azureDevOpsError: azuredevops.WrappedError{TypeKey: s(AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound)},
shouldReturnError: false,
},
{
name: "azure devops error with unknown error type returns error",
azureDevOpsError: azuredevops.WrappedError{TypeKey: new("OtherError")},
azureDevOpsError: azuredevops.WrappedError{TypeKey: s("OtherError")},
shouldReturnError: true,
},
{
@@ -176,12 +181,12 @@ func TestGetAllBranchesOnDisabledRepo(t *testing.T) {
}{
{
name: "azure devops error when disabled repo causes empty return value",
azureDevOpsError: azuredevops.WrappedError{TypeKey: new(AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound)},
azureDevOpsError: azuredevops.WrappedError{TypeKey: s(AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound)},
shouldReturnError: false,
},
{
name: "azure devops error with unknown error type returns error",
azureDevOpsError: azuredevops.WrappedError{TypeKey: new("OtherError")},
azureDevOpsError: azuredevops.WrappedError{TypeKey: s("OtherError")},
shouldReturnError: true,
},
{
@@ -229,7 +234,7 @@ func TestAzureDevOpsGetDefaultBranchStripsRefsName(t *testing.T) {
strippedBranchName := "somebranch"
defaultBranch := fmt.Sprintf("refs/heads/%v", strippedBranchName)
branchReturn := &azureGit.GitBranchStats{Name: &strippedBranchName, Commit: &azureGit.GitCommitRef{CommitId: new("abc123233223")}}
branchReturn := &azureGit.GitBranchStats{Name: &strippedBranchName, Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}}
repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch}
gitClientMock := &azureMock.Client{}
@@ -268,7 +273,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
}{
{
name: "GetBranches AllBranches false when single branch returned returns branch",
expectedBranch: &azureGit.GitBranchStats{Name: &defaultBranch, Commit: &azureGit.GitCommitRef{CommitId: new("abc123233223")}},
expectedBranch: &azureGit.GitBranchStats{Name: &defaultBranch, Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}},
},
{
name: "GetBranches AllBranches false when request fails returns error and empty result",
@@ -280,7 +285,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
},
{
name: "GetBranches AllBranches false when branch returned with long commit SHA",
expectedBranch: &azureGit.GitBranchStats{Name: &defaultBranch, Commit: &azureGit.GitCommitRef{CommitId: new("53863052ADF24229AB72154B4D83DAB7")}},
expectedBranch: &azureGit.GitBranchStats{Name: &defaultBranch, Commit: &azureGit.GitCommitRef{CommitId: s("53863052ADF24229AB72154B4D83DAB7")}},
},
}
@@ -339,7 +344,7 @@ func TestAzureDevopsGetBranches(t *testing.T) {
}{
{
name: "GetBranches when single branch returned returns this branch info",
expectedBranches: &[]azureGit.GitBranchStats{{Name: new("feature-feat1"), Commit: &azureGit.GitCommitRef{CommitId: new("abc123233223")}}},
expectedBranches: &[]azureGit.GitBranchStats{{Name: s("feature-feat1"), Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}}},
allBranches: true,
},
{
@@ -360,9 +365,9 @@ func TestAzureDevopsGetBranches(t *testing.T) {
{
name: "GetBranches when multiple branches returned returns branch info for all branches",
expectedBranches: &[]azureGit.GitBranchStats{
{Name: new("feature-feat1"), Commit: &azureGit.GitCommitRef{CommitId: new("abc123233223")}},
{Name: new("feature/feat2"), Commit: &azureGit.GitCommitRef{CommitId: new("4334")}},
{Name: new("feature/feat2"), Commit: &azureGit.GitCommitRef{CommitId: new("53863052ADF24229AB72154B4D83DAB7")}},
{Name: s("feature-feat1"), Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}},
{Name: s("feature/feat2"), Commit: &azureGit.GitCommitRef{CommitId: s("4334")}},
{Name: s("feature/feat2"), Commit: &azureGit.GitCommitRef{CommitId: s("53863052ADF24229AB72154B4D83DAB7")}},
},
allBranches: true,
},
@@ -429,12 +434,12 @@ func TestGetAzureDevopsRepositories(t *testing.T) {
}{
{
name: "ListRepos when single repo found returns repo info",
repositories: []azureGit.GitRepository{{Name: new("repo1"), DefaultBranch: new("main"), RemoteUrl: new("https://remoteurl.u"), Id: repoId}},
repositories: []azureGit.GitRepository{{Name: s("repo1"), DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}},
expectedNumberOfRepos: 1,
},
{
name: "ListRepos when repo has no default branch returns empty list",
repositories: []azureGit.GitRepository{{Name: new("repo2"), RemoteUrl: new("https://remoteurl.u"), Id: repoId}},
repositories: []azureGit.GitRepository{{Name: s("repo2"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}},
},
{
name: "ListRepos when Azure DevOps request fails returns error",
@@ -442,24 +447,24 @@ func TestGetAzureDevopsRepositories(t *testing.T) {
},
{
name: "ListRepos when repo has no name returns empty list",
repositories: []azureGit.GitRepository{{DefaultBranch: new("main"), RemoteUrl: new("https://remoteurl.u"), Id: repoId}},
repositories: []azureGit.GitRepository{{DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}},
},
{
name: "ListRepos when repo has no remote URL returns empty list",
repositories: []azureGit.GitRepository{{DefaultBranch: new("main"), Name: new("repo_name"), Id: repoId}},
repositories: []azureGit.GitRepository{{DefaultBranch: s("main"), Name: s("repo_name"), Id: repoId}},
},
{
name: "ListRepos when repo has no ID returns empty list",
repositories: []azureGit.GitRepository{{DefaultBranch: new("main"), Name: new("repo_name"), RemoteUrl: new("https://remoteurl.u")}},
repositories: []azureGit.GitRepository{{DefaultBranch: s("main"), Name: s("repo_name"), RemoteUrl: s("https://remoteurl.u")}},
},
{
name: "ListRepos when multiple repos returned returns list of eligible repos only",
repositories: []azureGit.GitRepository{
{Name: new("returned1"), DefaultBranch: new("main"), RemoteUrl: new("https://remoteurl.u"), Id: repoId},
{Name: new("missing_default_branch"), RemoteUrl: new("https://remoteurl.u"), Id: repoId},
{DefaultBranch: new("missing_name"), RemoteUrl: new("https://remoteurl.u"), Id: repoId},
{Name: new("missing_remote_url"), DefaultBranch: new("main"), Id: repoId},
{Name: new("missing_id"), DefaultBranch: new("main"), RemoteUrl: new("https://remoteurl.u")},
{Name: s("returned1"), DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u"), Id: repoId},
{Name: s("missing_default_branch"), RemoteUrl: s("https://remoteurl.u"), Id: repoId},
{DefaultBranch: s("missing_name"), RemoteUrl: s("https://remoteurl.u"), Id: repoId},
{Name: s("missing_remote_url"), DefaultBranch: s("main"), Id: repoId},
{Name: s("missing_id"), DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u")},
},
expectedNumberOfRepos: 1,
},
@@ -468,7 +473,7 @@ func TestGetAzureDevopsRepositories(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
gitClientMock := azureMock.NewClient(t)
gitClientMock.EXPECT().GetRepositories(mock.Anything, azureGit.GetRepositoriesArgs{Project: new(teamProject)}).Return(&testCase.repositories, testCase.getRepositoriesError)
gitClientMock.EXPECT().GetRepositories(mock.Anything, azureGit.GetRepositoriesArgs{Project: s(teamProject)}).Return(&testCase.repositories, testCase.getRepositoriesError)
clientFactoryMock := &mocks.AzureDevOpsClientFactory{}
clientFactoryMock.EXPECT().GetClient(mock.Anything).Return(gitClientMock, nil)

View File

@@ -445,6 +445,7 @@ func TestListReposTLS(t *testing.T) {
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defaultHandler(t)(w, r)

View File

@@ -1100,7 +1100,7 @@ func TestGitlabListRepos(t *testing.T) {
url: "git@gitlab.com:test-argocd-proton/argocd.git",
filters: []v1alpha1.SCMProviderGeneratorFilter{
{
LabelMatch: new("test-topic"),
LabelMatch: strp("test-topic"),
},
},
},
@@ -1301,6 +1301,7 @@ func TestGetBranchesTLS(t *testing.T) {
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gitlabMockHandler(t)(w, r)

View File

@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"regexp"
"slices"
"strings"
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -59,7 +58,13 @@ func matchFilter(ctx context.Context, provider SCMProviderService, repo *Reposit
}
if filter.LabelMatch != nil {
found := slices.ContainsFunc(repo.Labels, filter.LabelMatch.MatchString)
found := false
for _, label := range repo.Labels {
if filter.LabelMatch.MatchString(label) {
found = true
break
}
}
if !found {
return false, nil
}

View File

@@ -10,6 +10,10 @@ import (
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
)
func strp(s string) *string {
return &s
}
func TestFilterRepoMatch(t *testing.T) {
provider := &MockProvider{
Repos: []*Repository{
@@ -29,7 +33,7 @@ func TestFilterRepoMatch(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
RepositoryMatch: new("n|hr"),
RepositoryMatch: strp("n|hr"),
},
}
repos, err := ListRepos(t.Context(), provider, filters, "")
@@ -58,7 +62,7 @@ func TestFilterLabelMatch(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
LabelMatch: new("^prod-.*$"),
LabelMatch: strp("^prod-.*$"),
},
}
repos, err := ListRepos(t.Context(), provider, filters, "")
@@ -127,7 +131,7 @@ func TestFilterRepoMatchBadRegexp(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
RepositoryMatch: new("("),
RepositoryMatch: strp("("),
},
}
_, err := ListRepos(t.Context(), provider, filters, "")
@@ -144,7 +148,7 @@ func TestFilterLabelMatchBadRegexp(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
LabelMatch: new("("),
LabelMatch: strp("("),
},
}
_, err := ListRepos(t.Context(), provider, filters, "")
@@ -178,7 +182,7 @@ func TestFilterBranchMatch(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
BranchMatch: new("w"),
BranchMatch: strp("w"),
},
}
repos, err := ListRepos(t.Context(), provider, filters, "")
@@ -209,8 +213,8 @@ func TestMultiFilterAnd(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
RepositoryMatch: new("w"),
LabelMatch: new("^prod-.*$"),
RepositoryMatch: strp("w"),
LabelMatch: strp("^prod-.*$"),
},
}
repos, err := ListRepos(t.Context(), provider, filters, "")
@@ -238,10 +242,10 @@ func TestMultiFilterOr(t *testing.T) {
}
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{
{
RepositoryMatch: new("e"),
RepositoryMatch: strp("e"),
},
{
LabelMatch: new("^prod-.*$"),
LabelMatch: strp("^prod-.*$"),
},
}
repos, err := ListRepos(t.Context(), provider, filters, "")

View File

@@ -216,6 +216,7 @@ spec:
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
foundApp := v1alpha1.Application{TypeMeta: appMeta}

View File

@@ -2,7 +2,6 @@ package utils
import (
"fmt"
"slices"
"sort"
"strconv"
"strings"
@@ -208,7 +207,12 @@ type Requirement struct {
}
func (r *Requirement) hasValue(value string) bool {
return slices.Contains(r.strValues, value)
for i := range r.strValues {
if r.strValues[i] == value {
return true
}
}
return false
}
func (r *Requirement) Matches(ls labels.Labels) bool {

View File

@@ -388,7 +388,8 @@ func invalidGenerators(applicationSetInfo *argoappsv1.ApplicationSet) (bool, map
for index, generator := range applicationSetInfo.Spec.Generators {
v := reflect.Indirect(reflect.ValueOf(generator))
found := false
for _, field := range v.Fields() {
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
if !field.CanInterface() {
continue
}

View File

@@ -107,8 +107,10 @@ func NewWebhookHandler(webhookParallelism int, argocdSettingsMgr *argosettings.S
func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
compLog := log.WithField("component", "applicationset-webhook")
for range webhookParallelism {
h.Go(func() {
for i := 0; i < webhookParallelism; i++ {
h.Add(1)
go func() {
defer h.Done()
for {
payload, ok := <-h.queue
if !ok {
@@ -116,7 +118,7 @@ func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
}
guard.RecoverAndLog(func() { h.HandleEvent(payload) }, compLog, panicMsgAppSet)
}
})
}()
}
}

View File

@@ -609,7 +609,7 @@ func fakeAppWithMatrixAndNestedGitGenerator(name, namespace, repo string) *v1alp
},
{
Matrix: &apiextensionsv1.JSON{
Raw: fmt.Appendf(nil, `{
Raw: []byte(fmt.Sprintf(`{
"Generators": [
{
"List": {
@@ -626,7 +626,7 @@ func fakeAppWithMatrixAndNestedGitGenerator(name, namespace, repo string) *v1alp
}
}
]
}`, repo),
}`, repo)),
},
},
},
@@ -707,7 +707,7 @@ func fakeAppWithMergeAndNestedGitGenerator(name, namespace, repo string) *v1alph
},
{
Merge: &apiextensionsv1.JSON{
Raw: fmt.Appendf(nil, `{
Raw: []byte(fmt.Sprintf(`{
"MergeKeys": ["server"],
"Generators": [
{
@@ -719,7 +719,7 @@ func fakeAppWithMergeAndNestedGitGenerator(name, namespace, repo string) *v1alph
}
}
]
}`, repo),
}`, repo)),
},
},
},

6
assets/swagger.json generated
View File

@@ -7695,11 +7695,11 @@
},
"namePrefix": {
"type": "string",
"title": "NamePrefix overrides the namePrefix in the kustomization.yaml for Kustomize apps"
"title": "NamePrefix is a prefix appended to resources for Kustomize apps"
},
"nameSuffix": {
"type": "string",
"title": "NameSuffix overrides the nameSuffix in the kustomization.yaml for Kustomize apps"
"title": "NameSuffix is a suffix appended to resources for Kustomize apps"
},
"namespace": {
"type": "string",
@@ -9756,7 +9756,7 @@
"type": "object",
"properties": {
"diff": {
"description": "Diff contains the JSON patch representing the difference between the live and target resource.\n\nDeprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences.",
"description": "Diff contains the JSON patch representing the difference between the live and target resource.\nDeprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences.",
"type": "string"
},
"group": {

View File

@@ -41,6 +41,8 @@ import (
)
const (
// CLIName is the name of the CLI
cliName = common.ApplicationController
// Default time in seconds for application resync period
defaultAppResyncPeriod = 120
// Default time in seconds for application resync period jitter
@@ -97,7 +99,7 @@ func NewCommand() *cobra.Command {
hydratorEnabled bool
)
command := cobra.Command{
Use: common.CommandApplicationController,
Use: cliName,
Short: "Run ArgoCD Application Controller",
Long: "ArgoCD application controller is a Kubernetes controller that continuously monitors running applications and compares the current, live state against the desired target state (as specified in the repo). This command runs Application Controller in the foreground. It can be configured by following options.",
DisableAutoGenTag: true,

View File

@@ -49,6 +49,10 @@ import (
var gitSubmoduleEnabled = env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true)
const (
cliName = common.ApplicationSetController
)
func NewCommand() *cobra.Command {
var (
clientConfig clientcmd.ClientConfig
@@ -83,7 +87,7 @@ func NewCommand() *cobra.Command {
_ = clientgoscheme.AddToScheme(scheme)
_ = appv1alpha1.AddToScheme(scheme)
command := cobra.Command{
Use: common.CommandApplicationSetController,
Use: cliName,
Short: "Starts Argo CD ApplicationSet controller",
DisableAutoGenTag: true,
RunE: func(c *cobra.Command, _ []string) error {
@@ -302,7 +306,7 @@ func NewCommand() *cobra.Command {
command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently")
command.Flags().StringSliceVar(&metricsAplicationsetLabels, "metrics-applicationset-labels", []string{}, "List of Application labels that will be added to the argocd_applicationset_labels metric")
command.Flags().BoolVar(&enableGitHubAPIMetrics, "enable-github-api-metrics", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_GITHUB_API_METRICS", false), "Enable GitHub API metrics for generators that use the GitHub API")
command.Flags().IntVar(&maxResourcesStatusCount, "max-resources-status-count", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT", 5000, 0, math.MaxInt), "Max number of resources stored in appset status.")
command.Flags().IntVar(&maxResourcesStatusCount, "max-resources-status-count", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT", 0, 0, math.MaxInt), "Max number of resources stored in appset status.")
return &command
}

View File

@@ -18,6 +18,11 @@ import (
traceutil "github.com/argoproj/argo-cd/v3/util/trace"
)
const (
// CLIName is the name of the CLI
cliName = "argocd-cmp-server"
)
func NewCommand() *cobra.Command {
var (
configFilePath string
@@ -27,7 +32,7 @@ func NewCommand() *cobra.Command {
otlpAttrs []string
)
command := cobra.Command{
Use: common.CommandCMPServer,
Use: cliName,
Short: "Run ArgoCD ConfigManagementPlugin Server",
Long: "ArgoCD ConfigManagementPlugin Server is an internal service which runs as sidecar container in reposerver deployment. The following configuration options are available:",
DisableAutoGenTag: true,

View File

@@ -35,7 +35,7 @@ func NewCommand() *cobra.Command {
metricsHost string
)
command := &cobra.Command{
Use: common.CommandCommitServer,
Use: "argocd-commit-server",
Short: "Run Argo CD Commit Server",
Long: "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.",
RunE: func(cmd *cobra.Command, _ []string) error {
@@ -91,11 +91,13 @@ func NewCommand() *cobra.Command {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
wg := sync.WaitGroup{}
wg.Go(func() {
wg.Add(1)
go func() {
s := <-sigCh
log.Printf("got signal %v, attempting graceful shutdown", s)
grpc.GracefulStop()
})
wg.Done()
}()
log.Println("starting grpc server")
err = grpc.Serve(listener)

View File

@@ -25,9 +25,13 @@ import (
"github.com/argoproj/argo-cd/v3/util/tls"
)
const (
cliName = "argocd-dex"
)
func NewCommand() *cobra.Command {
command := &cobra.Command{
Use: common.CommandDex,
Use: cliName,
Short: "argocd-dex tools used by Argo CD",
Long: "argocd-dex has internal utility tools used by Argo CD",
DisableAutoGenTag: true,

View File

@@ -9,16 +9,20 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/argoproj/argo-cd/v3/common"
"github.com/argoproj/argo-cd/v3/util/askpass"
"github.com/argoproj/argo-cd/v3/util/errors"
grpc_util "github.com/argoproj/argo-cd/v3/util/grpc"
utilio "github.com/argoproj/argo-cd/v3/util/io"
)
const (
// cliName is the name of the CLI
cliName = "argocd-git-ask-pass"
)
func NewCommand() *cobra.Command {
command := cobra.Command{
Use: common.CommandGitAskPass,
Use: cliName,
Short: "Argo CD git credential helper",
DisableAutoGenTag: true,
Run: func(c *cobra.Command, _ []string) {

View File

@@ -2,13 +2,15 @@ package commands
import (
"github.com/spf13/cobra"
)
"github.com/argoproj/argo-cd/v3/common"
const (
cliName = "argocd-k8s-auth"
)
func NewCommand() *cobra.Command {
command := &cobra.Command{
Use: common.CommandK8sAuth,
Use: cliName,
Short: "argocd-k8s-auth a set of commands to generate k8s auth token",
DisableAutoGenTag: true,
Run: func(c *cobra.Command, args []string) {

View File

@@ -6,14 +6,12 @@ import (
"encoding/json"
"fmt"
"os"
"strconv"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
smithyhttp "github.com/aws/smithy-go/transport/http"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientauthv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
@@ -60,13 +58,13 @@ func newAWSCommand() *cobra.Command {
return command
}
type getSignedRequestFunc func(ctx context.Context, clusterName, roleARN string, profile string) (string, error)
type getSignedRequestFunc func(clusterName, roleARN string, profile string) (string, error)
func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Duration, clusterName, roleARN string, profile string, fn getSignedRequestFunc) (string, error) {
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
for {
signed, err := fn(ctx, clusterName, roleARN, profile)
signed, err := fn(clusterName, roleARN, profile)
if err == nil {
return signed, nil
}
@@ -78,53 +76,25 @@ func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Durat
}
}
func getSignedRequest(ctx context.Context, clusterName, roleARN string, profile string) (string, error) {
cfg, err := loadAWSConfig(ctx, profile)
func getSignedRequest(clusterName, roleARN string, profile string) (string, error) {
sess, err := session.NewSessionWithOptions(session.Options{
Profile: profile,
})
if err != nil {
return "", err
return "", fmt.Errorf("error creating new AWS session: %w", err)
}
return getSignedRequestWithConfig(ctx, clusterName, roleARN, cfg)
}
func loadAWSConfig(ctx context.Context, profile string) (aws.Config, error) {
var opts []func(*config.LoadOptions) error
if profile != "" {
opts = append(opts, config.WithSharedConfigProfile(profile))
}
cfg, err := config.LoadDefaultConfig(ctx, opts...)
if err != nil {
return aws.Config{}, fmt.Errorf("error loading AWS configuration: %w", err)
}
return cfg, nil
}
// getSignedRequestWithConfig presigns GetCallerIdentity using the given config. Used by getSignedRequest and by tests
// that inject a config with static credentials to exercise the roleARN path without real AWS credentials.
func getSignedRequestWithConfig(ctx context.Context, clusterName, roleARN string, cfg aws.Config) (string, error) {
// Use PresignOptions.ClientOptions + SetHeaderValue (same as aws-iam-authenticator) so the
// canonical request matches what EKS sends when validating. Build middleware can produce
// a different canonical form and thus an invalid signature for EKS.
// See kubernetes-sigs/aws-iam-authenticator pkg/token/token.go GetWithSTS().
client := sts.NewFromConfig(cfg)
stsAPI := sts.New(sess)
if roleARN != "" {
appCreds := stscreds.NewAssumeRoleProvider(client, roleARN)
cfg.Credentials = aws.NewCredentialsCache(appCreds)
client = sts.NewFromConfig(cfg)
creds := stscreds.NewCredentials(sess, roleARN)
stsAPI = sts.New(sess, &aws.Config{Credentials: creds})
}
presignClient := sts.NewPresignClient(client)
presigned, err := presignClient.PresignGetCallerIdentity(ctx, &sts.GetCallerIdentityInput{},
func(presignOptions *sts.PresignOptions) {
presignOptions.ClientOptions = append(presignOptions.ClientOptions, func(stsOptions *sts.Options) {
stsOptions.APIOptions = append(stsOptions.APIOptions,
smithyhttp.SetHeaderValue(clusterIDHeader, clusterName),
smithyhttp.SetHeaderValue("X-Amz-Expires", strconv.Itoa(requestPresignParam)))
})
})
request, _ := stsAPI.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{})
request.HTTPRequest.Header.Add(clusterIDHeader, clusterName)
signed, err := request.Presign(requestPresignParam)
if err != nil {
return "", fmt.Errorf("error presigning AWS request: %w", err)
}
return presigned.URL, nil
return signed, nil
}
func formatJSON(token string, expiration time.Time) string {

View File

@@ -1,60 +1,14 @@
package commands
import (
"context"
"errors"
"testing"
"time"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetSignedRequest(t *testing.T) {
t.Parallel()
t.Run("returns error when context is cancelled", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
cancel()
url, err := getSignedRequest(ctx, "my-cluster", "", "")
require.ErrorIs(t, err, context.Canceled)
assert.Empty(t, url)
})
t.Run("returns error for non-existent profile", func(t *testing.T) {
t.Parallel()
ctx := context.Background()
profile := "argocd-k8s-auth-test-nonexistent-profile-12345"
url, err := getSignedRequest(ctx, "my-cluster", "", profile)
require.Error(t, err)
assert.Empty(t, url)
assert.Contains(t, err.Error(), "configuration", "error should mention configuration load failed")
})
t.Run("returns error when roleARN is provided and assume role fails", func(t *testing.T) {
t.Parallel()
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx,
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider("test", "test", "")),
config.WithRegion("us-east-1"),
)
require.NoError(t, err)
url, err := getSignedRequestWithConfig(ctx, "my-cluster", "arn:aws:iam::123456789012:role/NonExistentRole", cfg)
require.Error(t, err)
assert.Empty(t, url)
assert.Contains(t, err.Error(), "presigning", "error should mention presigning failed when assume role is used")
})
}
func TestGetSignedRequestWithRetry(t *testing.T) {
t.Parallel()
@@ -118,7 +72,7 @@ type signedRequestMock struct {
returnFunc func(m *signedRequestMock) (string, error)
}
func (m *signedRequestMock) getSignedRequestMock(_ context.Context, _, _ string, _ string) (string, error) {
func (m *signedRequestMock) getSignedRequestMock(_, _ string, _ string) (string, error) {
m.getSignedRequestCalls++
return m.returnFunc(m)
}

View File

@@ -52,7 +52,7 @@ func NewCommand() *cobra.Command {
selfServiceNotificationEnabled bool
)
command := cobra.Command{
Use: common.CommandNotifications,
Use: "controller",
Short: "Starts Argo CD Notifications controller",
RunE: func(_ *cobra.Command, _ []string) error {
ctx, cancel := context.WithCancel(context.Background())
@@ -150,11 +150,13 @@ func NewCommand() *cobra.Command {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
wg := sync.WaitGroup{}
wg.Go(func() {
wg.Add(1)
go func() {
defer wg.Done()
s := <-sigCh
log.Printf("got signal %v, attempting graceful shutdown", s)
cancel()
})
}()
go ctrl.Run(ctx, processorsCount)
<-ctx.Done()

View File

@@ -34,18 +34,21 @@ import (
"github.com/argoproj/argo-cd/v3/util/gpg"
"github.com/argoproj/argo-cd/v3/util/healthz"
utilio "github.com/argoproj/argo-cd/v3/util/io"
"github.com/argoproj/argo-cd/v3/util/profile"
"github.com/argoproj/argo-cd/v3/util/tls"
traceutil "github.com/argoproj/argo-cd/v3/util/trace"
)
const (
// CLIName is the name of the CLI
cliName = "argocd-repo-server"
)
var (
gnuPGSourcePath = env.StringFromEnv(common.EnvGPGDataPath, "/app/config/gpg/source")
pauseGenerationAfterFailedGenerationAttempts = env.ParseNumFromEnv(common.EnvPauseGenerationAfterFailedAttempts, 3, 0, math.MaxInt32)
pauseGenerationOnFailureForMinutes = env.ParseNumFromEnv(common.EnvPauseGenerationMinutes, 60, 0, math.MaxInt32)
pauseGenerationOnFailureForRequests = env.ParseNumFromEnv(common.EnvPauseGenerationRequests, 0, 0, math.MaxInt32)
gitSubmoduleEnabled = env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true)
helmUserAgent = env.StringFromEnv(common.EnvHelmUserAgent, "")
)
func NewCommand() *cobra.Command {
@@ -80,7 +83,7 @@ func NewCommand() *cobra.Command {
enableBuiltinGitConfig bool
)
command := cobra.Command{
Use: common.CommandRepoServer,
Use: cliName,
Short: "Run ArgoCD Repository Server",
Long: "ArgoCD Repository Server is an internal service which maintains a local cache of the Git repository holding the application manifests, and is responsible for generating and returning the Kubernetes manifests. This command runs Repository Server in the foreground. It can be configured by following options.",
DisableAutoGenTag: true,
@@ -154,7 +157,6 @@ func NewCommand() *cobra.Command {
CMPUseManifestGeneratePaths: cmpUseManifestGeneratePaths,
OCIMediaTypes: ociMediaTypes,
EnableBuiltinGitConfig: enableBuiltinGitConfig,
HelmUserAgent: helmUserAgent,
}, askPassServer)
errors.CheckError(err)
@@ -173,8 +175,7 @@ func NewCommand() *cobra.Command {
listener, err := lc.Listen(ctx, "tcp", fmt.Sprintf("%s:%d", listenHost, listenPort))
errors.CheckError(err)
mux := http.NewServeMux()
healthz.ServeHealthCheck(mux, func(r *http.Request) error {
healthz.ServeHealthCheck(http.DefaultServeMux, func(r *http.Request) error {
if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" {
// connect to itself to make sure repo server is able to serve connection
// used by liveness probe to auto restart repo server
@@ -196,9 +197,8 @@ func NewCommand() *cobra.Command {
}
return nil
})
mux.Handle("/metrics", metricsServer.GetHandler())
profile.RegisterProfiler(mux)
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), mux)) }()
http.Handle("/metrics", metricsServer.GetHandler())
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), nil)) }()
go func() { errors.CheckError(askPassServer.Run()) }()
if gpg.IsGPGEnabled() {
@@ -223,11 +223,13 @@ func NewCommand() *cobra.Command {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
wg := sync.WaitGroup{}
wg.Go(func() {
wg.Add(1)
go func() {
s := <-sigCh
log.Printf("got signal %v, attempting graceful shutdown", s)
grpc.GracefulStop()
})
wg.Done()
}()
log.Println("starting grpc server")
err = grpc.Serve(listener)

View File

@@ -101,7 +101,7 @@ func NewCommand() *cobra.Command {
enableK8sEvent []string
)
command := &cobra.Command{
Use: common.CommandServer,
Use: cliName,
Short: "Run the ArgoCD API server",
Long: "The API server is a gRPC/REST server which exposes the API consumed by the Web UI, CLI, and CI/CD systems. This command runs API server in the foreground. It can be configured by following options.",
DisableAutoGenTag: true,
@@ -307,7 +307,7 @@ func NewCommand() *cobra.Command {
command.Flags().BoolVar(&disableAuth, "disable-auth", env.ParseBoolFromEnv("ARGOCD_SERVER_DISABLE_AUTH", false), "Disable client authentication")
command.Flags().StringVar(&contentTypes, "api-content-types", env.StringFromEnv("ARGOCD_API_CONTENT_TYPES", "application/json", env.StringFromEnvOpts{AllowEmpty: true}), "Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty.")
command.Flags().BoolVar(&enableGZip, "enable-gzip", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_GZIP", true), "Enable GZIP compression")
command.AddCommand(cli.NewVersionCmd(common.CommandServer))
command.AddCommand(cli.NewVersionCmd(cliName))
command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_SERVER_LISTEN_ADDRESS", common.DefaultAddressAPIServer), "Listen on given address")
command.Flags().IntVar(&listenPort, "port", common.DefaultPortAPIServer, "Listen on given port")
command.Flags().StringVar(&metricsHost, env.StringFromEnv("ARGOCD_SERVER_METRICS_LISTEN_ADDRESS", "metrics-address"), common.DefaultAddressAPIServerMetrics, "Listen for metrics on given address")

View File

@@ -0,0 +1,6 @@
package commands
const (
// cliName is the name of the CLI
cliName = "argocd-server"
)

View File

@@ -183,9 +183,9 @@ func getAdditionalNamespaces(ctx context.Context, configMapsClient dynamic.Resou
namespacesListFromString := func(namespaces string) []string {
listOfNamespaces := []string{}
ss := strings.SplitSeq(namespaces, ",")
ss := strings.Split(namespaces, ",")
for namespace := range ss {
for _, namespace := range ss {
if namespace != "" {
listOfNamespaces = append(listOfNamespaces, strings.TrimSpace(namespace))
}

View File

@@ -10,8 +10,8 @@ import (
"sort"
"time"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -3,9 +3,9 @@ package admin
import (
"testing"
clustermocks "github.com/argoproj/argo-cd/gitops-engine/pkg/cache/mocks"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
clustermocks "github.com/argoproj/gitops-engine/pkg/cache/mocks"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"

View File

@@ -8,7 +8,7 @@ import (
"strings"
"time"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
apierrors "k8s.io/apimachinery/pkg/api/errors"

View File

@@ -7,7 +7,7 @@ import (
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/util/security"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -10,7 +10,7 @@ import (
"text/tabwriter"
"time"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/redis/go-redis/v9"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -20,6 +20,7 @@ import (
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/utils/ptr"
cmdutil "github.com/argoproj/argo-cd/v3/cmd/util"
"github.com/argoproj/argo-cd/v3/common"
@@ -127,16 +128,19 @@ func loadClusters(ctx context.Context, kubeClient kubernetes.Interface, appClien
batchSize := 10
batchesCount := int(math.Ceil(float64(len(clusters)) / float64(batchSize)))
for batchNum := range batchesCount {
for batchNum := 0; batchNum < batchesCount; batchNum++ {
batchStart := batchSize * batchNum
batchEnd := min((batchSize * (batchNum + 1)), len(clustersList.Items))
batchEnd := batchSize * (batchNum + 1)
if batchEnd > len(clustersList.Items) {
batchEnd = len(clustersList.Items)
}
batch := clustersList.Items[batchStart:batchEnd]
_ = kube.RunAllAsync(len(batch), func(i int) error {
clusterShard := 0
cluster := batch[i]
if replicas > 0 {
clusterShard = clusterShards[cluster.Server]
cluster.Shard = new(int64(clusterShard))
cluster.Shard = ptr.To(int64(clusterShard))
log.Infof("Cluster with uid: %s will be processed by shard %d", cluster.ID, clusterShard)
}
if shard != -1 && clusterShard != shard {

View File

@@ -14,6 +14,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/utils/ptr"
)
func Test_loadClusters(t *testing.T) {
@@ -73,7 +74,7 @@ func Test_loadClusters(t *testing.T) {
},
ServerVersion: ".",
},
Shard: new(int64(0)),
Shard: ptr.To(int64(0)),
},
Namespaces: []string{"test"},
}}

View File

@@ -7,7 +7,7 @@ import (
"io"
"os"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml"

View File

@@ -17,7 +17,7 @@ import (
utilio "github.com/argoproj/argo-cd/v3/util/io"
"github.com/argoproj/argo-cd/v3/util/templates"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/clientcmd"

View File

@@ -23,7 +23,7 @@ func generateRandomPassword() (string, error) {
const initialPasswordLength = 16
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
randBytes := make([]byte, initialPasswordLength)
for i := range initialPasswordLength {
for i := 0; i < initialPasswordLength; i++ {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
if err != nil {
return "", err

View File

@@ -7,13 +7,12 @@ import (
"fmt"
"os"
"reflect"
"slices"
"sort"
"strconv"
"strings"
"text/tabwriter"
healthutil "github.com/argoproj/argo-cd/gitops-engine/pkg/health"
healthutil "github.com/argoproj/gitops-engine/pkg/health"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
@@ -272,7 +271,9 @@ func NewValidateSettingsCommand(cmdCtx commandContext) *cobra.Command {
for k := range validatorsByGroup {
allGroups = append(allGroups, k)
}
slices.Sort(allGroups)
sort.Slice(allGroups, func(i, j int) bool {
return allGroups[i] < allGroups[j]
})
command := &cobra.Command{
Use: "validate",

View File

@@ -322,7 +322,6 @@ func getPolicy(ctx context.Context, policyFile string, kubeClient kubernetes.Int
}
// getPolicyFromFile loads a RBAC policy from given path
// nolint:unparam // complains about the error being always nil which is false-positive
func getPolicyFromFile(policyFile string) (string, string, string, error) {
var (
userPolicy string

View File

@@ -19,11 +19,11 @@ import (
"golang.org/x/sync/errgroup"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/hook"
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/ignore"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/argoproj/gitops-engine/pkg/sync/hook"
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry"
"github.com/mattn/go-isatty"
log "github.com/sirupsen/logrus"
@@ -35,6 +35,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
k8swatch "k8s.io/apimachinery/pkg/watch"
"k8s.io/utils/ptr"
"sigs.k8s.io/yaml"
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless"
@@ -45,7 +46,7 @@ import (
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
"github.com/argoproj/argo-cd/v3/pkg/apiclient/application"
resourceutil "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/resource"
resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource"
clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"
projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project"
@@ -601,17 +602,17 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
stream, err := appIf.PodLogs(ctx, &application.ApplicationPodLogsQuery{
Name: &appName,
Group: &group,
Namespace: new(namespace),
Namespace: ptr.To(namespace),
Kind: &kind,
ResourceName: &resourceName,
Follow: new(follow),
TailLines: new(tail),
SinceSeconds: new(sinceSeconds),
Follow: ptr.To(follow),
TailLines: ptr.To(tail),
SinceSeconds: ptr.To(sinceSeconds),
UntilTime: &untilTime,
Filter: &filter,
MatchCase: new(matchCase),
Container: new(container),
Previous: new(previous),
MatchCase: ptr.To(matchCase),
Container: ptr.To(container),
Previous: ptr.To(previous),
AppNamespace: &appNs,
})
if err != nil {
@@ -1871,7 +1872,7 @@ func NewApplicationListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie()
defer utilio.Close(conn)
apps, err := appIf.List(ctx, &application.ApplicationQuery{
Selector: new(selector),
Selector: ptr.To(selector),
AppNamespace: &appNamespace,
})
@@ -1987,8 +1988,8 @@ func parseSelectedResources(resources []string) ([]*argoappv1.SyncOperationResou
for _, resource := range resources {
isExcluded := false
// check if the resource flag starts with a '!'
if after, ok := strings.CutPrefix(resource, resourceExcludeIndicator); ok {
resource = after
if strings.HasPrefix(resource, resourceExcludeIndicator) {
resource = strings.TrimPrefix(resource, resourceExcludeIndicator)
isExcluded = true
}
fields := strings.Split(resource, resourceFieldDelimiter)
@@ -2072,7 +2073,7 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
closer, appIf := acdClient.NewApplicationClientOrDie()
defer utilio.Close(closer)
if selector != "" {
list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: new(selector)})
list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: ptr.To(selector)})
errors.CheckError(err)
for _, i := range list.Items {
appNames = append(appNames, i.QualifiedName())
@@ -2256,7 +2257,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
appNames := args
if selector != "" || len(projects) > 0 {
list, err := appIf.List(ctx, &application.ApplicationQuery{
Selector: new(selector),
Selector: ptr.To(selector),
AppNamespace: &appNamespace,
Projects: projects,
})
@@ -2430,7 +2431,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
Backoff: &argoappv1.Backoff{
Duration: retryBackoffDuration.String(),
MaxDuration: retryBackoffMaxDuration.String(),
Factor: new(retryBackoffFactor),
Factor: ptr.To(retryBackoffFactor),
},
}
}
@@ -2524,7 +2525,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
func getAppNamesBySelector(ctx context.Context, appIf application.ApplicationServiceClient, selector string) ([]string, error) {
appNames := []string{}
if selector != "" {
list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: new(selector)})
list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: ptr.To(selector)})
if err != nil {
return []string{}, err
}
@@ -2702,7 +2703,7 @@ func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string
func resourceParentChild(ctx context.Context, acdClient argocdclient.Client, appName string, appNs string) (map[string]argoappv1.ResourceNode, map[string][]string, map[string]struct{}, map[string]*resourceState) {
_, appIf := acdClient.NewApplicationClientOrDie()
mapUIDToNode, mapParentToChild, parentNode := parentChildDetails(ctx, appIf, appName, appNs)
app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: new(appName), AppNamespace: new(appNs)})
app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: ptr.To(appName), AppNamespace: ptr.To(appNs)})
errors.CheckError(err)
mapNodeNameToResourceState := make(map[string]*resourceState)
for _, res := range getResourceStates(app, nil) {
@@ -3134,8 +3135,8 @@ func NewApplicationRollbackCommand(clientOpts *argocdclient.ClientOptions) *cobr
_, err = appIf.Rollback(ctx, &application.ApplicationRollbackRequest{
Name: &appName,
AppNamespace: &appNs,
Id: new(depInfo.ID),
Prune: new(prune),
Id: ptr.To(depInfo.ID),
Prune: ptr.To(prune),
})
errors.CheckError(err)
@@ -3287,7 +3288,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
q := application.ApplicationManifestQuery{
Name: &appName,
AppNamespace: &appNs,
Revision: new(revision),
Revision: ptr.To(revision),
Revisions: revisions,
SourcePositions: sourcePositions,
}
@@ -3303,7 +3304,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
q := application.ApplicationManifestQuery{
Name: &appName,
AppNamespace: &appNs,
Revision: new(revision),
Revision: ptr.To(revision),
}
res, err := appIf.GetManifests(ctx, &q)
errors.CheckError(err)
@@ -3325,6 +3326,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
default:
log.Fatalf("Unknown source type '%s'", source)
}
for _, obj := range unstructureds {
fmt.Println("---")
yamlBytes, err := yaml.Marshal(obj)
@@ -3664,7 +3666,7 @@ func NewApplicationConfirmDeletionCommand(clientOpts *argocdclient.ClientOptions
_, err = appIf.Update(ctx, &application.ApplicationUpdateRequest{
Application: app,
Validate: new(false),
Validate: ptr.To(false),
Project: &app.Spec.Project,
})
errors.CheckError(err)

View File

@@ -11,6 +11,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/grpc/codes"
"k8s.io/utils/ptr"
"sigs.k8s.io/yaml"
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless"
@@ -94,11 +95,11 @@ func NewApplicationResourceActionsListCommand(clientOpts *argocdclient.ClientOpt
availActionsForResource, err := appIf.ListResourceActions(ctx, &applicationpkg.ApplicationResourceRequest{
Name: &appName,
AppNamespace: &appNs,
Namespace: new(obj.GetNamespace()),
ResourceName: new(obj.GetName()),
Group: new(gvk.Group),
Kind: new(gvk.Kind),
Version: new(gvk.Version),
Namespace: ptr.To(obj.GetNamespace()),
ResourceName: ptr.To(obj.GetName()),
Group: ptr.To(gvk.Group),
Kind: ptr.To(gvk.Kind),
Version: ptr.To(gvk.Version),
})
errors.CheckError(err)
for _, action := range availActionsForResource.Actions {
@@ -194,12 +195,12 @@ func NewApplicationResourceActionsRunCommand(clientOpts *argocdclient.ClientOpti
_, err := appIf.RunResourceActionV2(ctx, &applicationpkg.ResourceActionRunRequestV2{
Name: &appName,
AppNamespace: &appNs,
Namespace: new(obj.GetNamespace()),
ResourceName: new(objResourceName),
Group: new(gvk.Group),
Kind: new(gvk.Kind),
Version: new(gvk.GroupVersion().Version),
Action: new(actionName),
Namespace: ptr.To(obj.GetNamespace()),
ResourceName: ptr.To(objResourceName),
Group: ptr.To(gvk.Group),
Kind: ptr.To(gvk.Kind),
Version: ptr.To(gvk.GroupVersion().Version),
Action: ptr.To(actionName),
// TODO: add support for parameters
})
if err == nil {
@@ -213,12 +214,12 @@ func NewApplicationResourceActionsRunCommand(clientOpts *argocdclient.ClientOpti
_, err = appIf.RunResourceAction(ctx, &applicationpkg.ResourceActionRunRequest{
Name: &appName,
AppNamespace: &appNs,
Namespace: new(obj.GetNamespace()),
ResourceName: new(objResourceName),
Group: new(gvk.Group),
Kind: new(gvk.Kind),
Version: new(gvk.GroupVersion().Version),
Action: new(actionName),
Namespace: ptr.To(obj.GetNamespace()),
ResourceName: ptr.To(objResourceName),
Group: ptr.To(gvk.Group),
Kind: ptr.To(gvk.Kind),
Version: ptr.To(gvk.GroupVersion().Version),
Action: ptr.To(actionName),
})
errors.CheckError(err)
}

View File

@@ -43,49 +43,9 @@ func TestPrintTreeViewAppResources(t *testing.T) {
printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w)
require.NoError(t, w.Flush())
output := buf.String()
t.Logf("Output:\n%s", output)
assert.Contains(t, output, "Rollout")
assert.Contains(t, output, "argoproj.io")
assert.Contains(t, output, "└─apps ReplicaSet sandbox-rollout-numalogic-demo numalogic-rollout-demo-5dcd5457d5 No")
assert.Contains(t, output, " └─ Pod sandbox-rollout-numalogic-demo numalogic-rollout-demo-5dcd5457d5-6trpt No")
}
func TestPrintTreeViewAppResourcesWithMultipleChildren(t *testing.T) {
var nodes [4]v1alpha1.ResourceNode
// Parent
nodes[0].ResourceRef = v1alpha1.ResourceRef{Group: "argoproj.io", Kind: "Rollout", Namespace: "ns", Name: "rollout", UID: "root"}
// Child 1
nodes[1].ResourceRef = v1alpha1.ResourceRef{Group: "apps", Kind: "ReplicaSet", Namespace: "ns", Name: "rs1", UID: "rs1"}
nodes[1].ParentRefs = []v1alpha1.ResourceRef{{UID: "root"}}
// Child 2
nodes[2].ResourceRef = v1alpha1.ResourceRef{Group: "apps", Kind: "ReplicaSet", Namespace: "ns", Name: "rs2", UID: "rs2"}
nodes[2].ParentRefs = []v1alpha1.ResourceRef{{UID: "root"}}
// Grandchild
nodes[3].ResourceRef = v1alpha1.ResourceRef{Group: "", Kind: "Pod", Namespace: "ns", Name: "pod1", UID: "pod1"}
nodes[3].ParentRefs = []v1alpha1.ResourceRef{{UID: "rs1"}}
nodeMapping := make(map[string]v1alpha1.ResourceNode)
mapParentToChild := make(map[string][]string)
parentNode := make(map[string]struct{})
for _, node := range nodes {
nodeMapping[node.UID] = node
if len(node.ParentRefs) > 0 {
mapParentToChild[node.ParentRefs[0].UID] = append(mapParentToChild[node.ParentRefs[0].UID], node.UID)
} else {
parentNode[node.UID] = struct{}{}
}
}
buf := &bytes.Buffer{}
w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0)
printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w)
require.NoError(t, w.Flush())
output := buf.String()
t.Logf("Output:\n%s", output)
assert.Contains(t, output, "├─apps ReplicaSet ns rs1")
assert.Contains(t, output, "│ └─ Pod ns pod1")
assert.Contains(t, output, "└─apps ReplicaSet ns rs2")
}
func TestPrintTreeViewDetailedAppResources(t *testing.T) {
@@ -122,11 +82,10 @@ func TestPrintTreeViewDetailedAppResources(t *testing.T) {
printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w)
require.NoError(t, w.Flush())
output := buf.String()
t.Logf("Output:\n%s", output)
assert.Contains(t, output, "argoproj.io Rollout sandbox-rollout-numalogic-demo numalogic-rollout-demo No <unknown> Degraded Readiness Gate failed")
assert.Contains(t, output, "└─apps ReplicaSet sandbox-rollout-numalogic-demo numalogic-rollout-demo-5dcd5457d5 No")
assert.Contains(t, output, " └─ Pod sandbox-rollout-numalogic-demo numalogic-rollout-demo-5dcd5457d5-6trpt No")
assert.Contains(t, output, "Rollout")
assert.Contains(t, output, "Degraded")
assert.Contains(t, output, "Readiness Gate failed")
}
func TestPrintResourcesTree(t *testing.T) {

View File

@@ -10,8 +10,6 @@ import (
"gopkg.in/yaml.v3"
"github.com/argoproj/argo-cd/v3/util/templates"
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/utils"
"github.com/argoproj/argo-cd/v3/cmd/util"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -20,6 +18,7 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless"
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
@@ -88,7 +87,7 @@ func NewApplicationGetResourceCommand(clientOpts *argocdclient.ClientOptions) *c
// Get manifests of resources
// If resource name is "" find all resources of that kind
var resources []unstructured.Unstructured
var resourceNames []string
var fetchedStr string
for _, r := range tree.Nodes {
if (resourceName != "" && r.Name != resourceName) || (group != "" && r.Group != group) || r.Kind != kind {
continue
@@ -118,11 +117,14 @@ func NewApplicationGetResourceCommand(clientOpts *argocdclient.ClientOptions) *c
obj = filterFieldsFromObject(obj, filteredFields)
}
resourceNames = append(resourceNames, obj.GetName())
fetchedStr += obj.GetName() + ", "
resources = append(resources, *obj)
}
fetchedStr := strings.Join(resourceNames, ", ")
printManifests(&resources, len(filteredFields) > 0, resourceName == "", output)
if fetchedStr != "" {
fetchedStr = strings.TrimSuffix(fetchedStr, ", ")
}
log.Infof("Resources '%s' fetched", fetchedStr)
}
@@ -336,14 +338,14 @@ func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions)
_, err = appIf.PatchResource(ctx, &applicationpkg.ApplicationResourcePatchRequest{
Name: &appName,
AppNamespace: &appNs,
Namespace: new(obj.GetNamespace()),
ResourceName: new(obj.GetName()),
Version: new(gvk.Version),
Group: new(gvk.Group),
Kind: new(gvk.Kind),
Patch: new(patch),
PatchType: new(patchType),
Project: new(project),
Namespace: ptr.To(obj.GetNamespace()),
ResourceName: ptr.To(obj.GetName()),
Version: ptr.To(gvk.Version),
Group: ptr.To(gvk.Group),
Kind: ptr.To(gvk.Kind),
Patch: ptr.To(patch),
PatchType: ptr.To(patchType),
Project: ptr.To(project),
})
errors.CheckError(err)
log.Infof("Resource '%s' patched", obj.GetName())
@@ -409,14 +411,14 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions)
_, err = appIf.DeleteResource(ctx, &applicationpkg.ApplicationResourceDeleteRequest{
Name: &appName,
AppNamespace: &appNs,
Namespace: new(obj.GetNamespace()),
ResourceName: new(obj.GetName()),
Version: new(gvk.Version),
Group: new(gvk.Group),
Kind: new(gvk.Kind),
Namespace: ptr.To(obj.GetNamespace()),
ResourceName: ptr.To(obj.GetName()),
Version: ptr.To(gvk.Version),
Group: ptr.To(gvk.Group),
Kind: ptr.To(gvk.Kind),
Force: &force,
Orphan: &orphan,
Project: new(project),
Project: ptr.To(project),
})
errors.CheckError(err)
log.Infof("Resource '%s' deleted", obj.GetName())
@@ -531,20 +533,7 @@ func NewApplicationListResourcesCommand(clientOpts *argocdclient.ClientOptions)
)
command := &cobra.Command{
Use: "resources APPNAME",
Short: "List resources of application",
Example: templates.Examples(`
# List first-level resources of application
argocd app resources my-app --refresh
# List only the orphaned resources of application
argocd app resources my-app --orphaned
# Shows resource hierarchy with parent-child relationships
argocd app resources my-app --output tree
# Shows resource hierarchy with parent-child relationships including information about age, health and reason
argocd app resources my-app --output tree=detailed
`),
Short: "List resource of application",
Run: func(c *cobra.Command, args []string) {
ctx := c.Context()
if len(args) != 1 {
@@ -565,9 +554,7 @@ func NewApplicationListResourcesCommand(clientOpts *argocdclient.ClientOptions)
},
}
command.Flags().BoolVar(&orphaned, "orphaned", false, "Lists only orphaned resources")
command.Flags().StringVar(&output, "output", "", `Output format. One of: tree|tree=detailed.
tree: Shows resource hierarchy with parent-child relationships
tree=detailed: Same as tree, but includes AGE, HEALTH, and REASON columns`)
command.Flags().StringVar(&output, "output", "", "Provides the tree view of the resources")
command.Flags().StringVar(&project, "project", "", `The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist`)
return command
}

View File

@@ -12,8 +12,8 @@ import (
"testing"
"time"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"

View File

@@ -91,7 +91,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
)
command := &cobra.Command{
Use: "add CONTEXT",
Short: common.CommandCLI + " cluster add CONTEXT",
Short: cliName + " cluster add CONTEXT",
Run: func(c *cobra.Command, args []string) {
ctx := c.Context()
@@ -549,7 +549,7 @@ argocd cluster list -o server <ARGOCD_SERVER_ADDRESS>
func NewClusterRotateAuthCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
command := &cobra.Command{
Use: "rotate-auth SERVER/NAME",
Short: common.CommandCLI + " cluster rotate-auth SERVER/NAME",
Short: cliName + " cluster rotate-auth SERVER/NAME",
Example: `argocd cluster rotate-auth https://12.34.567.89
argocd cluster rotate-auth cluster-name`,
Run: func(c *cobra.Command, args []string) {

View File

@@ -9,6 +9,8 @@ import (
)
const (
cliName = "argocd"
// DefaultSSOLocalPort is the localhost port to listen on for the temporary web server performing
// the OAuth2 login flow.
DefaultSSOLocalPort = 8085

View File

@@ -22,6 +22,7 @@ import (
"k8s.io/client-go/kubernetes"
cache2 "k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/initialize"
@@ -208,7 +209,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti
log.SetLevel(log.ErrorLevel)
os.Setenv(v1alpha1.EnvVarFakeInClusterConfig, "true")
if address == nil {
address = new("localhost")
address = ptr.To("localhost")
}
if port == nil || *port == 0 {
addr := *address + ":0"
@@ -301,7 +302,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti
}
tries := 5
for range tries {
for i := 0; i < tries; i++ {
err = testAPI(ctx, clientOpts)
if err == nil {
break

View File

@@ -170,9 +170,9 @@ func (h *DefaultPluginHandler) ListAvailablePlugins() []string {
// Check if the file is a valid argocd plugin
pluginPrefix := prefix + "-"
if after, ok := strings.CutPrefix(name, pluginPrefix); ok {
if strings.HasPrefix(name, pluginPrefix) {
// Extract the plugin command name (everything after the prefix)
pluginName := after
pluginName := strings.TrimPrefix(name, pluginPrefix)
// Skip empty plugin names or names with path separators
if pluginName == "" || strings.Contains(pluginName, "/") || strings.Contains(pluginName, "\\") {

View File

@@ -362,7 +362,7 @@ argocd proj windows list test-project`,
func printSyncWindows(proj *v1alpha1.AppProject) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
var fmtStr string
headers := []any{"ID", "STATUS", "KIND", "SCHEDULE", "DURATION", "APPLICATIONS", "NAMESPACES", "CLUSTERS", "MANUALSYNC", "TIMEZONE", "USEANDOPERATOR"}
headers := []any{"ID", "STATUS", "KIND", "SCHEDULE", "DURATION", "APPLICATIONS", "NAMESPACES", "CLUSTERS", "MANUALSYNC", "TIMEZONE"}
fmtStr = strings.Repeat("%s\t", len(headers)) + "\n"
fmt.Fprintf(w, fmtStr, headers...)
if proj.Spec.SyncWindows.HasWindows() {

View File

@@ -1,40 +0,0 @@
package commands
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
)
func TestPrintSyncWindows(t *testing.T) {
proj := &v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "test-project"},
Spec: v1alpha1.AppProjectSpec{
SyncWindows: v1alpha1.SyncWindows{
{
Kind: "allow",
Schedule: "* * * * *",
Duration: "1h",
Applications: []string{"app1"},
Namespaces: []string{"ns1"},
Clusters: []string{"cluster1"},
ManualSync: true,
UseAndOperator: true,
},
},
},
}
output, err := captureOutput(func() error {
printSyncWindows(proj)
return nil
})
require.NoError(t, err)
t.Log(output)
assert.Contains(t, output, "ID STATUS KIND SCHEDULE DURATION APPLICATIONS NAMESPACES CLUSTERS MANUALSYNC TIMEZONE USEANDOPERATOR")
assert.Contains(t, output, "0 Active allow * * * * * 1h app1 ns1 cluster1 Enabled Enabled")
}

View File

@@ -37,7 +37,7 @@ func NewCommand() *cobra.Command {
)
command := &cobra.Command{
Use: common.CommandCLI,
Use: cliName,
Short: "argocd controls a Argo CD server",
Run: func(c *cobra.Command, args []string) {
c.HelpFunc()(c, args)

View File

@@ -6,7 +6,7 @@ import (
"text/tabwriter"
"time"
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/health"
"k8s.io/apimachinery/pkg/util/duration"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -15,6 +15,7 @@ import (
const (
firstElemPrefix = `├─`
lastElemPrefix = `└─`
indent = " "
pipe = ``
)
@@ -74,7 +75,9 @@ func detailedTreeViewAppGet(prefix string, uidToNodeMap map[string]v1alpha1.Reso
}
func treeViewAppResourcesNotOrphaned(prefix string, uidToNodeMap map[string]v1alpha1.ResourceNode, parentChildMap map[string][]string, parent v1alpha1.ResourceNode, w *tabwriter.Writer) {
_, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\t%s\n", printPrefix(prefix), parent.Group, parent.Kind, parent.Namespace, parent.Name, "No")
if len(parent.ParentRefs) == 0 {
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", parent.Group, parent.Kind, parent.Namespace, parent.Name, "No")
}
chs := parentChildMap[parent.UID]
for i, child := range chs {
var p string
@@ -89,7 +92,7 @@ func treeViewAppResourcesNotOrphaned(prefix string, uidToNodeMap map[string]v1al
}
func treeViewAppResourcesOrphaned(prefix string, uidToNodeMap map[string]v1alpha1.ResourceNode, parentChildMap map[string][]string, parent v1alpha1.ResourceNode, w *tabwriter.Writer) {
_, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\t%s\n", printPrefix(prefix), parent.Group, parent.Kind, parent.Namespace, parent.Name, "Yes")
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", parent.Group, parent.Kind, parent.Namespace, parent.Name, "Yes")
chs := parentChildMap[parent.UID]
for i, child := range chs {
var p string
@@ -104,12 +107,14 @@ func treeViewAppResourcesOrphaned(prefix string, uidToNodeMap map[string]v1alpha
}
func detailedTreeViewAppResourcesNotOrphaned(prefix string, uidToNodeMap map[string]v1alpha1.ResourceNode, parentChildMap map[string][]string, parent v1alpha1.ResourceNode, w *tabwriter.Writer) {
healthStatus, reason := extractHealthStatusAndReason(parent)
age := "<unknown>"
if parent.CreatedAt != nil {
age = duration.HumanDuration(time.Since(parent.CreatedAt.Time))
if len(parent.ParentRefs) == 0 {
healthStatus, reason := extractHealthStatusAndReason(parent)
age := "<unknown>"
if parent.CreatedAt != nil {
age = duration.HumanDuration(time.Since(parent.CreatedAt.Time))
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", parent.Group, parent.Kind, parent.Namespace, parent.Name, "No", age, healthStatus, reason)
}
_, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", printPrefix(prefix), parent.Group, parent.Kind, parent.Namespace, parent.Name, "No", age, healthStatus, reason)
chs := parentChildMap[parent.UID]
for i, child := range chs {
var p string
@@ -129,7 +134,7 @@ func detailedTreeViewAppResourcesOrphaned(prefix string, uidToNodeMap map[string
if parent.CreatedAt != nil {
age = duration.HumanDuration(time.Since(parent.CreatedAt.Time))
}
_, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", printPrefix(prefix), parent.Group, parent.Kind, parent.Namespace, parent.Name, "Yes", age, healthStatus, reason)
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", parent.Group, parent.Kind, parent.Namespace, parent.Name, "Yes", age, healthStatus, reason)
chs := parentChildMap[parent.UID]
for i, child := range chs {

View File

@@ -48,7 +48,7 @@ func NewVersionCmd(clientOpts *argocdclient.ClientOptions, serverVersion *versio
v := make(map[string]any)
if short {
v["client"] = map[string]string{common.CommandCLI: cv.Version}
v["client"] = map[string]string{cliName: cv.Version}
} else {
v["client"] = cv
}
@@ -103,7 +103,7 @@ func getServerVersion(ctx context.Context, options *argocdclient.ClientOptions,
}
func printClientVersion(version *common.Version, short bool) string {
output := fmt.Sprintf("%s: %s\n", common.CommandCLI, version)
output := fmt.Sprintf("%s: %s\n", cliName, version)
if short {
return output
}

View File

@@ -20,7 +20,6 @@ import (
reposerver "github.com/argoproj/argo-cd/v3/cmd/argocd-repo-server/commands"
apiserver "github.com/argoproj/argo-cd/v3/cmd/argocd-server/commands"
cli "github.com/argoproj/argo-cd/v3/cmd/argocd/commands"
"github.com/argoproj/argo-cd/v3/common"
"github.com/argoproj/argo-cd/v3/util/log"
)
@@ -44,34 +43,33 @@ func main() {
isArgocdCLI := false
switch binaryName {
case common.CommandCLI:
case "argocd", "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe":
command = cli.NewCommand()
isArgocdCLI = true
case common.CommandServer:
case "argocd-server":
command = apiserver.NewCommand()
case common.CommandApplicationController:
case "argocd-application-controller":
command = appcontroller.NewCommand()
case common.CommandRepoServer:
case "argocd-repo-server":
command = reposerver.NewCommand()
case common.CommandCMPServer:
case "argocd-cmp-server":
command = cmpserver.NewCommand()
isArgocdCLI = true
case common.CommandCommitServer:
case "argocd-commit-server":
command = commitserver.NewCommand()
case common.CommandDex:
case "argocd-dex":
command = dex.NewCommand()
case common.CommandNotifications:
case "argocd-notifications":
command = notification.NewCommand()
case common.CommandGitAskPass:
case "argocd-git-ask-pass":
command = gitaskpass.NewCommand()
isArgocdCLI = true
case common.CommandApplicationSetController:
case "argocd-applicationset-controller":
command = applicationset.NewCommand()
case common.CommandK8sAuth:
case "argocd-k8s-auth":
command = k8sauth.NewCommand()
isArgocdCLI = true
default:
// "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe" are also valid binary names
command = cli.NewCommand()
isArgocdCLI = true
}

View File

@@ -5,7 +5,6 @@ import (
stderrors "errors"
"fmt"
"io"
"maps"
"net/url"
"os"
"strings"
@@ -13,12 +12,13 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
"github.com/argoproj/argo-cd/v3/pkg/apis/application"
argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -240,8 +240,8 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap
}
for _, option := range appOpts.syncOptions {
// `!` means remove the option
if after, ok := strings.CutPrefix(option, "!"); ok {
option = after
if strings.HasPrefix(option, "!") {
option = strings.TrimPrefix(option, "!")
spec.SyncPolicy.SyncOptions = spec.SyncPolicy.SyncOptions.RemoveOption(option)
} else {
spec.SyncPolicy.SyncOptions = spec.SyncPolicy.SyncOptions.AddOption(option)
@@ -261,7 +261,7 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap
Backoff: &argoappv1.Backoff{
Duration: appOpts.retryBackoffDuration.String(),
MaxDuration: appOpts.retryBackoffMaxDuration.String(),
Factor: new(appOpts.retryBackoffFactor),
Factor: ptr.To(appOpts.retryBackoffFactor),
},
Refresh: appOpts.retryRefresh,
}
@@ -847,9 +847,13 @@ func mergeLabels(app *argoappv1.Application, labels []string) {
mergedLabels := make(map[string]string)
maps.Copy(mergedLabels, app.GetLabels())
for name, value := range app.GetLabels() {
mergedLabels[name] = value
}
maps.Copy(mergedLabels, mapLabels)
for name, value := range mapLabels {
mergedLabels[name] = value
}
app.SetLabels(mergedLabels)
}

View File

@@ -5,7 +5,7 @@ import (
"net/url"
"os"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/util/config"

View File

@@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
"github.com/argoproj/argo-cd/v3/pkg/apis/application"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -145,7 +146,7 @@ func GetOrphanedResourcesSettings(flagSet *pflag.FlagSet, opts ProjectOpts) *v1a
if opts.orphanedResourcesEnabled || warnChanged {
settings := v1alpha1.OrphanedResourcesMonitorSettings{}
if warnChanged {
settings.Warn = new(opts.orphanedResourcesWarn)
settings.Warn = ptr.To(opts.orphanedResourcesWarn)
}
return &settings
}

View File

@@ -24,7 +24,7 @@ import (
argoexec "github.com/argoproj/argo-cd/v3/util/exec"
"github.com/argoproj/argo-cd/v3/util/io/files"
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/mattn/go-zglob"
log "github.com/sirupsen/logrus"

View File

@@ -1,4 +1,5 @@
//go:build !windows
// +build !windows
package plugin

View File

@@ -1,4 +1,5 @@
//go:build windows
// +build windows
package plugin

View File

@@ -43,14 +43,10 @@ type CommitHydratedManifestsRequest struct {
// Paths contains the paths to write hydrated manifests to, along with the manifests and commands to execute.
Paths []*PathDetails `protobuf:"bytes,6,rep,name=paths,proto3" json:"paths,omitempty"`
// DryCommitMetadata contains metadata about the DRY commit, such as the author and committer.
DryCommitMetadata *v1alpha1.RevisionMetadata `protobuf:"bytes,7,opt,name=dryCommitMetadata,proto3" json:"dryCommitMetadata,omitempty"`
// AuthorName is the author name to use for the commit. If empty, defaults to "Argo CD".
AuthorName string `protobuf:"bytes,8,opt,name=authorName,proto3" json:"authorName,omitempty"`
// AuthorEmail is the author email to use for the commit. If empty, defaults to "argo-cd@example.com".
AuthorEmail string `protobuf:"bytes,9,opt,name=authorEmail,proto3" json:"authorEmail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
DryCommitMetadata *v1alpha1.RevisionMetadata `protobuf:"bytes,7,opt,name=dryCommitMetadata,proto3" json:"dryCommitMetadata,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CommitHydratedManifestsRequest) Reset() { *m = CommitHydratedManifestsRequest{} }
@@ -135,20 +131,6 @@ func (m *CommitHydratedManifestsRequest) GetDryCommitMetadata() *v1alpha1.Revisi
return nil
}
func (m *CommitHydratedManifestsRequest) GetAuthorName() string {
if m != nil {
return m.AuthorName
}
return ""
}
func (m *CommitHydratedManifestsRequest) GetAuthorEmail() string {
if m != nil {
return m.AuthorEmail
}
return ""
}
// PathDetails holds information about hydrated manifests to be written to a particular path in the hydrated manifests
// commit.
type PathDetails struct {
@@ -325,39 +307,37 @@ func init() {
func init() { proto.RegisterFile("commitserver/commit/commit.proto", fileDescriptor_cf3a3abbc35e3069) }
var fileDescriptor_cf3a3abbc35e3069 = []byte{
// 505 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0x41, 0x6f, 0xd3, 0x30,
0x14, 0x56, 0xd6, 0xae, 0xac, 0xee, 0x76, 0xc0, 0x07, 0x66, 0xf5, 0x90, 0x45, 0x11, 0x87, 0x5e,
0x70, 0xb4, 0x56, 0x70, 0xe3, 0xb2, 0x82, 0x34, 0x21, 0x56, 0x50, 0x7a, 0x43, 0x93, 0xd0, 0x5b,
0x62, 0x12, 0xb3, 0x24, 0x36, 0xb6, 0x1b, 0x29, 0x12, 0x3f, 0x90, 0x23, 0x3f, 0x01, 0x55, 0xfc,
0x10, 0x14, 0x27, 0xa1, 0x29, 0xa8, 0xec, 0xc0, 0x29, 0x7e, 0xdf, 0x7b, 0xf9, 0x3e, 0xbf, 0xef,
0xf9, 0x21, 0x2f, 0x12, 0x79, 0xce, 0x8d, 0x66, 0xaa, 0x64, 0x2a, 0x68, 0x82, 0xf6, 0x43, 0xa5,
0x12, 0x46, 0x4c, 0xdf, 0x26, 0xdc, 0xa4, 0x9b, 0x3b, 0x1a, 0x89, 0x3c, 0x00, 0x95, 0x08, 0xa9,
0xc4, 0x67, 0x7b, 0x78, 0x16, 0xc5, 0x41, 0xb9, 0x08, 0xe4, 0x7d, 0x12, 0x80, 0xe4, 0x3a, 0x00,
0x29, 0x33, 0x1e, 0x81, 0xe1, 0xa2, 0x08, 0xca, 0x4b, 0xc8, 0x64, 0x0a, 0x97, 0x41, 0xc2, 0x0a,
0xa6, 0xc0, 0xb0, 0xb8, 0x61, 0xf3, 0x7f, 0x0e, 0x90, 0xbb, 0xb4, 0xf4, 0xd7, 0x55, 0x6c, 0x13,
0x37, 0x50, 0xf0, 0x4f, 0x4c, 0x1b, 0x1d, 0xb2, 0x2f, 0x1b, 0xa6, 0x0d, 0xbe, 0x45, 0x43, 0xc5,
0xa4, 0x20, 0x8e, 0xe7, 0xcc, 0x26, 0xf3, 0x6b, 0xba, 0xd3, 0xa7, 0x9d, 0xbe, 0x3d, 0x7c, 0x8c,
0x62, 0x5a, 0x2e, 0xa8, 0xbc, 0x4f, 0x68, 0xad, 0x4f, 0x7b, 0xfa, 0xb4, 0xd3, 0xa7, 0x21, 0x93,
0x42, 0x73, 0x23, 0x54, 0x15, 0x5a, 0x56, 0xec, 0x22, 0xa4, 0xab, 0x22, 0xba, 0x52, 0x50, 0x44,
0x29, 0x39, 0xf2, 0x9c, 0xd9, 0x38, 0xec, 0x21, 0xd8, 0x47, 0xa7, 0x06, 0x54, 0xc2, 0x4c, 0x5b,
0x31, 0xb0, 0x15, 0x7b, 0x18, 0x7e, 0x82, 0x46, 0xb1, 0xaa, 0xd6, 0x29, 0x90, 0xa1, 0xcd, 0xb6,
0x11, 0x7e, 0x8a, 0xce, 0x1a, 0xeb, 0x6e, 0x98, 0xd6, 0x90, 0x30, 0x72, 0x6c, 0xd3, 0xfb, 0x20,
0xf6, 0xd1, 0xb1, 0x04, 0x93, 0x6a, 0x32, 0xf2, 0x06, 0xb3, 0xc9, 0xfc, 0x94, 0xbe, 0x07, 0x93,
0xbe, 0x62, 0x06, 0x78, 0xa6, 0xc3, 0x26, 0x85, 0xbf, 0xa2, 0xc7, 0xb1, 0xaa, 0x96, 0xed, 0x7f,
0x06, 0x62, 0x30, 0x40, 0x1e, 0x59, 0x43, 0x56, 0xff, 0x6b, 0x48, 0xc9, 0x35, 0x17, 0x45, 0xc7,
0x1a, 0xfe, 0x2d, 0x54, 0x7b, 0x04, 0x1b, 0x93, 0x0a, 0xb5, 0x82, 0x9c, 0x91, 0x93, 0xc6, 0xa3,
0x1d, 0x82, 0x3d, 0x34, 0x69, 0xa2, 0xd7, 0x39, 0xf0, 0x8c, 0x8c, 0x6d, 0x41, 0x1f, 0xf2, 0x37,
0x68, 0xd2, 0xeb, 0x0a, 0x63, 0x34, 0xac, 0xfb, 0xb2, 0x23, 0x1d, 0x87, 0xf6, 0x8c, 0x5f, 0xa0,
0x71, 0xde, 0x8d, 0x9e, 0x1c, 0x59, 0x2b, 0x08, 0xfd, 0xf3, 0x51, 0x74, 0xb6, 0xec, 0x4a, 0xf1,
0x14, 0x9d, 0xd4, 0x7e, 0x42, 0x11, 0x6b, 0x32, 0xf0, 0x06, 0xb3, 0x71, 0xf8, 0x3b, 0xf6, 0x5f,
0xa2, 0xf3, 0x03, 0x0c, 0xf5, 0x5c, 0x3b, 0x8e, 0x37, 0xeb, 0x77, 0xab, 0xf6, 0x2a, 0x7b, 0x98,
0xbf, 0x44, 0x17, 0x07, 0xdf, 0xa6, 0x96, 0xa2, 0xd0, 0xb6, 0xf5, 0xb4, 0x4d, 0xd6, 0xf3, 0x6f,
0x58, 0xfa, 0xd0, 0x3c, 0x47, 0x67, 0x0d, 0xc9, 0x9a, 0xa9, 0x92, 0x47, 0x0c, 0xdf, 0xa2, 0xf3,
0x03, 0xac, 0xf8, 0x82, 0xfe, 0x7b, 0x17, 0xa6, 0x1e, 0x7d, 0xe0, 0x42, 0x57, 0xcb, 0x6f, 0x5b,
0xd7, 0xf9, 0xbe, 0x75, 0x9d, 0x1f, 0x5b, 0xd7, 0xf9, 0xf0, 0xfc, 0x81, 0x65, 0xdd, 0xdb, 0x76,
0x90, 0x3c, 0xca, 0x38, 0x2b, 0xcc, 0xdd, 0xc8, 0x2e, 0xe7, 0xe2, 0x57, 0x00, 0x00, 0x00, 0xff,
0xff, 0x58, 0x7e, 0x26, 0x9f, 0x0e, 0x04, 0x00, 0x00,
// 479 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x95, 0xeb, 0x34, 0x90, 0x49, 0x7b, 0x60, 0x0f, 0xd4, 0xca, 0xc1, 0xb5, 0x2c, 0x0e, 0xb9,
0xb0, 0x56, 0x13, 0xc1, 0x8d, 0x4b, 0xc3, 0xa1, 0x42, 0xb4, 0x20, 0xe7, 0x86, 0x2a, 0xa1, 0xa9,
0xbd, 0xd8, 0x4b, 0x63, 0xef, 0xb2, 0xbb, 0xb1, 0x64, 0x89, 0xaf, 0xe1, 0x6b, 0x38, 0xf2, 0x09,
0x28, 0x5f, 0x82, 0xbc, 0xb6, 0x69, 0x02, 0x0a, 0x39, 0x70, 0xf2, 0xce, 0xbc, 0xf1, 0x7b, 0xb3,
0xf3, 0x76, 0x20, 0x48, 0x44, 0x51, 0x70, 0xa3, 0x99, 0xaa, 0x98, 0x8a, 0xda, 0xa0, 0xfb, 0x50,
0xa9, 0x84, 0x11, 0x93, 0xb7, 0x19, 0x37, 0xf9, 0xfa, 0x8e, 0x26, 0xa2, 0x88, 0x50, 0x65, 0x42,
0x2a, 0xf1, 0xd9, 0x1e, 0x9e, 0x27, 0x69, 0x54, 0xcd, 0x23, 0x79, 0x9f, 0x45, 0x28, 0xb9, 0x8e,
0x50, 0xca, 0x15, 0x4f, 0xd0, 0x70, 0x51, 0x46, 0xd5, 0x05, 0xae, 0x64, 0x8e, 0x17, 0x51, 0xc6,
0x4a, 0xa6, 0xd0, 0xb0, 0xb4, 0x65, 0x0b, 0xbf, 0xb9, 0xe0, 0x2f, 0x2c, 0xfd, 0x55, 0x9d, 0x5a,
0xe0, 0x1a, 0x4b, 0xfe, 0x89, 0x69, 0xa3, 0x63, 0xf6, 0x65, 0xcd, 0xb4, 0x21, 0xb7, 0x30, 0x50,
0x4c, 0x0a, 0xcf, 0x09, 0x9c, 0xe9, 0x78, 0x76, 0x45, 0x1f, 0xf4, 0x69, 0xaf, 0x6f, 0x0f, 0x1f,
0x93, 0x94, 0x56, 0x73, 0x2a, 0xef, 0x33, 0xda, 0xe8, 0xd3, 0x2d, 0x7d, 0xda, 0xeb, 0xd3, 0x98,
0x49, 0xa1, 0xb9, 0x11, 0xaa, 0x8e, 0x2d, 0x2b, 0xf1, 0x01, 0x74, 0x5d, 0x26, 0x97, 0x0a, 0xcb,
0x24, 0xf7, 0x8e, 0x02, 0x67, 0x3a, 0x8a, 0xb7, 0x32, 0x24, 0x84, 0x13, 0x83, 0x2a, 0x63, 0xa6,
0xab, 0x70, 0x6d, 0xc5, 0x4e, 0x8e, 0x3c, 0x85, 0x61, 0xaa, 0xea, 0x65, 0x8e, 0xde, 0xc0, 0xa2,
0x5d, 0x44, 0x9e, 0xc1, 0x69, 0x3b, 0xba, 0x6b, 0xa6, 0x35, 0x66, 0xcc, 0x3b, 0xb6, 0xf0, 0x6e,
0x92, 0x84, 0x70, 0x2c, 0xd1, 0xe4, 0xda, 0x1b, 0x06, 0xee, 0x74, 0x3c, 0x3b, 0xa1, 0xef, 0xd1,
0xe4, 0xaf, 0x99, 0x41, 0xbe, 0xd2, 0x71, 0x0b, 0x91, 0xaf, 0xf0, 0x24, 0x55, 0xf5, 0xa2, 0xfb,
0xcf, 0x60, 0x8a, 0x06, 0xbd, 0x47, 0x76, 0x20, 0x37, 0xff, 0x3b, 0x90, 0x8a, 0x6b, 0x2e, 0xca,
0x9e, 0x35, 0xfe, 0x5b, 0x28, 0x5c, 0xc3, 0x78, 0xab, 0x27, 0x42, 0x60, 0xd0, 0x74, 0x65, 0x0d,
0x19, 0xc5, 0xf6, 0x4c, 0x5e, 0xc2, 0xa8, 0xe8, 0x8d, 0xf3, 0x8e, 0xec, 0x45, 0x3c, 0xfa, 0xa7,
0xa5, 0xfd, 0xa5, 0x1e, 0x4a, 0xc9, 0x04, 0x1e, 0x37, 0xd3, 0xc0, 0x32, 0xd5, 0x9e, 0x1b, 0xb8,
0xd3, 0x51, 0xfc, 0x3b, 0x0e, 0x5f, 0xc1, 0xd9, 0x1e, 0x86, 0xc6, 0x95, 0x9e, 0xe3, 0xcd, 0xf2,
0xdd, 0x4d, 0xd7, 0xca, 0x4e, 0x2e, 0x5c, 0xc0, 0xf9, 0xde, 0x97, 0xa5, 0xa5, 0x28, 0x35, 0x23,
0x01, 0x8c, 0xf3, 0x0e, 0x6c, 0xdc, 0x6b, 0x59, 0xb6, 0x53, 0xb3, 0x02, 0x4e, 0x5b, 0x92, 0x25,
0x53, 0x15, 0x4f, 0x18, 0xb9, 0x85, 0xb3, 0x3d, 0xac, 0xe4, 0x9c, 0xfe, 0xfb, 0x25, 0x4f, 0x02,
0x7a, 0xa0, 0xa1, 0xcb, 0xc5, 0xf7, 0x8d, 0xef, 0xfc, 0xd8, 0xf8, 0xce, 0xcf, 0x8d, 0xef, 0x7c,
0x78, 0x71, 0x60, 0xd5, 0x76, 0x76, 0x15, 0x25, 0x4f, 0x56, 0x9c, 0x95, 0xe6, 0x6e, 0x68, 0x57,
0x6b, 0xfe, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x21, 0x3b, 0xa8, 0x3c, 0xcc, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -466,20 +446,6 @@ func (m *CommitHydratedManifestsRequest) MarshalToSizedBuffer(dAtA []byte) (int,
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.AuthorEmail) > 0 {
i -= len(m.AuthorEmail)
copy(dAtA[i:], m.AuthorEmail)
i = encodeVarintCommit(dAtA, i, uint64(len(m.AuthorEmail)))
i--
dAtA[i] = 0x4a
}
if len(m.AuthorName) > 0 {
i -= len(m.AuthorName)
copy(dAtA[i:], m.AuthorName)
i = encodeVarintCommit(dAtA, i, uint64(len(m.AuthorName)))
i--
dAtA[i] = 0x42
}
if m.DryCommitMetadata != nil {
{
size, err := m.DryCommitMetadata.MarshalToSizedBuffer(dAtA[:i])
@@ -721,14 +687,6 @@ func (m *CommitHydratedManifestsRequest) Size() (n int) {
l = m.DryCommitMetadata.Size()
n += 1 + l + sovCommit(uint64(l))
}
l = len(m.AuthorName)
if l > 0 {
n += 1 + l + sovCommit(uint64(l))
}
l = len(m.AuthorEmail)
if l > 0 {
n += 1 + l + sovCommit(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -1064,70 +1022,6 @@ func (m *CommitHydratedManifestsRequest) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AuthorName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCommit
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthCommit
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthCommit
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AuthorName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AuthorEmail", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCommit
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthCommit
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthCommit
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AuthorEmail = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipCommit(dAtA[iNdEx:])

View File

@@ -35,7 +35,7 @@ func TestAddNoteConcurrentStaggered(t *testing.T) {
// Create separate clones for concurrent operations
cloneClients := make([]git.Client, 3)
for i := range 3 {
for i := 0; i < 3; i++ {
cloneClients[i] = getClientForClone(t, remotePath)
}
@@ -43,7 +43,7 @@ func TestAddNoteConcurrentStaggered(t *testing.T) {
var wg sync.WaitGroup
errors := make([]error, 3)
for i := range 3 {
for i := 0; i < 3; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
@@ -81,7 +81,7 @@ func TestAddNoteConcurrentSimultaneous(t *testing.T) {
// Create separate clones for concurrent operations
cloneClients := make([]git.Client, 3)
for i := range 3 {
for i := 0; i < 3; i++ {
cloneClients[i] = getClientForClone(t, remotePath)
}
@@ -89,7 +89,7 @@ func TestAddNoteConcurrentSimultaneous(t *testing.T) {
var wg sync.WaitGroup
startChan := make(chan struct{})
for i := range 3 {
for i := 0; i < 3; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()

View File

@@ -272,19 +272,16 @@ func (s *Service) initGitClient(logCtx *log.Entry, r *apiclient.CommitHydratedMa
// cleanupOrLog()
// return nil, "", nil, fmt.Errorf("failed to get github app info: %w", err)
// }
// Use author name and email from request, defaulting to "Argo CD" if not provided
authorName := r.AuthorName
var authorName, authorEmail string
if authorName == "" {
authorName = "Argo CD"
}
authorEmail := r.AuthorEmail
if authorEmail == "" {
logCtx.Warnf("Author email not available, using 'argo-cd@example.com'.")
authorEmail = "argo-cd@example.com"
}
logCtx.Debugf("Author config: request name='%s', request email='%s', final name='%s', final email='%s'",
r.AuthorName, r.AuthorEmail, authorName, authorEmail)
logCtx.Debugf("Setting author %s <%s>", authorName, authorEmail)
_, err = gitClient.SetAuthor(authorName, authorEmail)
if err != nil {

View File

@@ -20,10 +20,6 @@ message CommitHydratedManifestsRequest {
repeated PathDetails paths = 6;
// DryCommitMetadata contains metadata about the DRY commit, such as the author and committer.
github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.RevisionMetadata dryCommitMetadata = 7;
// AuthorName is the author name to use for the commit. If empty, defaults to "Argo CD".
string authorName = 8;
// AuthorEmail is the author email to use for the commit. If empty, defaults to "argo-cd@example.com".
string authorEmail = 9;
}
// PathDetails holds information about hydrated manifests to be written to a particular path in the hydrated manifests

Some files were not shown because too many files have changed in this diff Show More