Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper platform handle gitcreds #62

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,12 @@ We welcome [issues](https://github.com/game-ci/unity-orb/issues) to and [pull re
5. Now ensure the version tag selected is semantically accurate based on the changes included.
6. Click _"Publish Release"_.
- This will push a new tag and trigger your publishing pipeline on CircleCI.

### Manual Deploy
If you want a private orb for your build env. The following steps allow you to do so. These are adapted from the CircleCI
[Manual Orb Authoring Process](https://circleci.com/docs/orb-author-validate-publish/#publish-your-orb)
1. `circleci namespace create <name> --org-id <your-organization-id>`
2. `circleci orb create <my-namespace>/<my-orb-name> --private`
3. `circleci orb pack src > unity-orb.yml`
4. `circleci orb publish unity-orb.yml <my-namespace>/<my-orb-name>@dev:first`
5. `circleci orb publish promote <my-namespace>/<my-orb-name>@dev:first patch`
17 changes: 17 additions & 0 deletions src/commands/prepare-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ parameters:
description: |
Enter the name of the environment variable containing your Unity license file encoded in base64.
Required if you have a Personal license.
git-private-token-var-name:
type: env_var_name
default: "GIT_PRIVATE_TOKEN"
description: |
Enter your Github PAT that you want to pass to the credential manager
cache-version:
type: string
default: "v1"
Expand Down Expand Up @@ -64,3 +69,15 @@ steps:
SCRIPT_PREPARE_ENV_MACOS: << include(scripts/macos/prepare-env.sh) >>
SCRIPT_UTILS: << include(scripts/utils.sh) >>
command: << include(scripts/prepare-env.sh) >>
- run:
name: Set Git Credentials
no_output_timeout: << parameters.no_output_timeout >>
environment:
PARAM_GIT_PRIVATE_TOKEN: << parameters.git-private-token-var-name >>
PARAM_PROJECT_PATH: << parameters.project-path >>
SCRIPT_UTILS: << include(scripts/utils.sh) >>
SCRIPT_GIT_CREDENTIAL_LINUX: << include(scripts/linux/set-gitcredential.sh) >>
SCRIPT_GIT_CREDENTIAL_WINDOWS: << include(scripts/windows/set-gitcredential.sh) >>
SCRIPT_GIT_CREDENTIAL_MACOS: << include(scripts/macos/set-gitcredential.sh) >>
command: << include(scripts/set-gitcredential.sh) >>
Comment on lines +72 to +82
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Security concerns identified in Git credential handling

Several security issues need to be addressed in the credential handling scripts:

  • The scripts expose credentials by printing the full git config (including tokens) to logs via git config --list
  • Using --global for git config affects the entire user environment instead of being scoped to the repository
  • No cleanup of credentials after the build process
  • Token is exposed in URL rewrites which may appear in logs

Key locations requiring changes:

  • src/scripts/linux/set-gitcredential.sh: Remove git config --list commands, use --local instead of --global
  • src/scripts/windows/set-gitcredential.sh: Remove config listing, use local scope
  • src/scripts/macos/set-gitcredential.sh: Same issues as Linux script

Recommended improvements:

  1. Replace --global with --local in all git config commands
  2. Remove the git config --list debug commands
  3. Add cleanup steps to remove credentials after use
  4. Consider using git credential store with input redirection instead of embedding tokens in URLs
🔗 Analysis chain

Verify secure credential handling in external scripts

The step correctly handles different operating systems, but we should verify the security of credential handling in the referenced scripts.

Let's check the referenced scripts for secure practices:

Additionally, consider these security improvements:

  1. Add a cleanup step to remove credentials after the build
  2. Use --local instead of --global for git config to avoid affecting other repositories

Let me gather more information about the scripts since the previous attempt didn't show their contents.


Let's examine the content of these scripts to understand the complete credential handling flow.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify credential handling in the external scripts
# Check for potential security issues in credential handling

# Check if scripts exist and examine their content
for script in "scripts/linux/set-gitcredential.sh" "scripts/windows/set-gitcredential.sh" "scripts/macos/set-gitcredential.sh"; do
  echo "Checking $script:"
  if [ -f "$script" ]; then
    # Look for potential security issues
    rg -i "echo.*token" "$script" || true
    rg "git.*config.*--global" "$script" || true
    rg "credential.helper" "$script" || true
  fi
done

Length of output: 833


Script:

#!/bin/bash
# Let's first find the actual location of these scripts
fd -t f "set-gitcredential.sh"

# Then let's examine the main script that orchestrates the credential setup
fd -t f "scripts/set-gitcredential.sh" || echo "Main script not found"

# Let's also check for any git credential related patterns in the entire codebase
rg -i "git.*credential" --type sh

Length of output: 1176


Script:

#!/bin/bash
# Check the content of all git credential related scripts
echo "=== Main orchestrator script ==="
cat src/scripts/set-gitcredential.sh

echo -e "\n=== Linux script ==="
cat src/scripts/linux/set-gitcredential.sh

echo -e "\n=== Windows script ==="
cat src/scripts/windows/set-gitcredential.sh

echo -e "\n=== MacOS script ==="
cat src/scripts/macos/set-gitcredential.sh

Length of output: 5005


6 changes: 6 additions & 0 deletions src/jobs/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ parameters:
description: |
Enter the name of the environment variable containing your Unity license file encoded in base64.
Required if you have a Personal license.
git-private-token-var-name:
type: env_var_name
default: "GIT_PRIVATE_TOKEN"
description: |
Enter your Github PAT that you want to pass to the credential manager
project-path:
type: string
default: "."
Expand Down Expand Up @@ -113,6 +118,7 @@ steps:
unity-password-var-name: << parameters.unity-password-var-name >>
unity-serial-var-name: << parameters.unity-serial-var-name >>
unity-license-var-name: << parameters.unity-license-var-name >>
git-private-token-var-name: << parameters.git-private-token-var-name >>
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Potential security concerns in git credential handling

The implementation reveals several security considerations:

  • The token is exposed in git config list output, which could leak sensitive information in CI logs
  • Multiple git config entries are created with the token in plaintext
  • The script shows git config --list output which includes credentials

Key locations requiring attention:

  • src/scripts/linux/set-gitcredential.sh: Remove or mask git config --list commands
  • Similar changes needed in Windows and macOS credential scripts
🔗 Analysis chain

Verify secure token handling in prepare-env scripts.

The parameter is correctly passed to prepare-env, but we should verify the secure handling of the token in the implementation.


Let me check the implementation details of these files to verify secure token handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check prepare-env implementation for secure token handling

# Check prepare-env command implementation
echo "Checking prepare-env command implementation:"
fd --type f "prepare-env.yml" src/commands

# Check related scripts for secure practices
echo -e "\nChecking credential scripts for secure practices:"
rg -l "GIT_PRIVATE_TOKEN" src/scripts

# Look for potential token exposure in logs
echo -e "\nChecking for potential token logging:"
rg --ignore-case "echo.*token|print.*token" src/scripts

Length of output: 1178


Script:

#!/bin/bash
# Check prepare-env command implementation
echo "=== Prepare-env command implementation ==="
cat src/commands/prepare-env.yml

echo -e "\n=== Linux git credential script ==="
cat src/scripts/linux/set-gitcredential.sh

echo -e "\n=== Check for direct token exposure in git commands ==="
rg "git.*\$GIT_PRIVATE_TOKEN" src/scripts/

Length of output: 5125

project-path: <<parameters.project-path>>
no_output_timeout: << parameters.no_output_timeout>>
- build:
Expand Down
25 changes: 25 additions & 0 deletions src/scripts/linux/set-gitcredential.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/false
# shellcheck shell=bash
# shellcheck disable=SC2154

if [ -z "${GIT_PRIVATE_TOKEN}" ]
then
echo "GIT_PRIVATE_TOKEN unset skipping"
else
echo "GIT_PRIVATE_TOKEN is set configuring git credentials"
Comment on lines +5 to +9
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Enhance security measures for token handling.

While the script checks if the token is set, consider adding:

  1. Token format validation
  2. Token length verification
  3. Warning about token exposure in git config

Consider adding basic validation:

 if [ -z "${GIT_PRIVATE_TOKEN}" ]
 then
   echo "GIT_PRIVATE_TOKEN unset skipping"
 else
+  # Validate token format and length
+  if [[ ! "${GIT_PRIVATE_TOKEN}" =~ ^gh[ps]_[a-zA-Z0-9]{36,255}$ ]]; then
+    echo "Error: Invalid GitHub token format" >&2
+    exit 1
+  fi
   echo "GIT_PRIVATE_TOKEN is set configuring git credentials"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ -z "${GIT_PRIVATE_TOKEN}" ]
then
echo "GIT_PRIVATE_TOKEN unset skipping"
else
echo "GIT_PRIVATE_TOKEN is set configuring git credentials"
if [ -z "${GIT_PRIVATE_TOKEN}" ]
then
echo "GIT_PRIVATE_TOKEN unset skipping"
else
# Validate token format and length
if [[ ! "${GIT_PRIVATE_TOKEN}" =~ ^gh[ps]_[a-zA-Z0-9]{36,255}$ ]]; then
echo "Error: Invalid GitHub token format" >&2
exit 1
fi
echo "GIT_PRIVATE_TOKEN is set configuring git credentials"


git config --global credential.helper store
git config --global --replace-all url."https://token:[email protected]/".insteadOf ssh://[email protected]/
git config --global --add url."https://token:[email protected]/".insteadOf [email protected]
git config --global --add url."https://token:[email protected]/".insteadOf "https://github.com/"

git config --global url."https://ssh:[email protected]/".insteadOf "ssh://[email protected]/"
git config --global url."https://git:[email protected]/".insteadOf "[email protected]:"

Comment on lines +11 to +18
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Limit the scope of Git configurations and enhance security.

Several security and scope concerns:

  1. Using --global affects all repositories
  2. credential.helper store saves credentials in plaintext
  3. No cleanup of sensitive configurations

Consider these improvements:

-git config --global credential.helper store
+# Use git credential cache instead of store
+git config credential.helper 'cache --timeout=3600'
 
-git config --global --replace-all url."https://token:[email protected]/".insteadOf ssh://[email protected]/
+# Scope configurations to the repository instead of global
+git config --replace-all url."https://token:[email protected]/".insteadOf ssh://[email protected]/

Also, add a cleanup function:

cleanup_git_config() {
  git config --unset-all url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf
  git config --unset credential.helper
}
trap cleanup_git_config EXIT

fi

echo "---------- git config --list -------------"
git --no-pager config --list

echo "---------- git config --list --show-origin -------------"
git --no-pager config --list --show-origin
Comment on lines +1 to +25
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Cross-platform scripts exist but macOS version is empty

The verification shows that:

  • All platforms (Linux, Windows, macOS) have corresponding scripts
  • Linux and Windows versions have consistent git credential configurations
  • The macOS version (src/scripts/macos/set-gitcredential.sh) exists but appears to be empty
  • There's also a root-level script with identical content to the Linux version
🔗 Analysis chain

Verify cross-platform consistency.

Ensure similar scripts exist for other platforms (Windows/macOS) with consistent behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for similar scripts in other platform directories
echo "Checking for platform-specific scripts..."
fd -t f "set-gitcredential" src/scripts

# Compare script contents for consistency
echo -e "\nComparing script contents..."
for script in $(fd -t f "set-gitcredential" src/scripts); do
  echo "=== $script ==="
  cat "$script" | grep -E "credential.helper|url\."
done

Length of output: 3324

Comment on lines +21 to +25
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Secure sensitive information in logs.

The current configuration display might leak sensitive tokens in logs. Consider filtering sensitive information before display.

Add filtering:

 echo "---------- git config --list -------------"
-git --no-pager config --list
+git --no-pager config --list | sed -e 's/\(url.*token:\)[^@]*\(@.*\)/\1[FILTERED]\2/'
 
 echo "---------- git config --list --show-origin -------------"
-git --no-pager config --list --show-origin
+git --no-pager config --list --show-origin | sed -e 's/\(url.*token:\)[^@]*\(@.*\)/\1[FILTERED]\2/'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "---------- git config --list -------------"
git --no-pager config --list
echo "---------- git config --list --show-origin -------------"
git --no-pager config --list --show-origin
echo "---------- git config --list -------------"
git --no-pager config --list | sed -e 's/\(url.*token:\)[^@]*\(@.*\)/\1[FILTERED]\2/'
echo "---------- git config --list --show-origin -------------"
git --no-pager config --list --show-origin | sed -e 's/\(url.*token:\)[^@]*\(@.*\)/\1[FILTERED]\2/'

25 changes: 25 additions & 0 deletions src/scripts/macos/set-gitcredential.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/false
# shellcheck shell=bash
# shellcheck disable=SC2154

Comment on lines +1 to +4
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace /bin/false with /bin/bash in shebang

The current shebang points to /bin/false, which would prevent the script from executing. While this might be intentional to prevent direct execution, it could cause issues when the script needs to run as part of the CI process.

-#!/bin/false
+#!/bin/bash
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/bin/false
# shellcheck shell=bash
# shellcheck disable=SC2154
#!/bin/bash
# shellcheck shell=bash
# shellcheck disable=SC2154

if [ -z "${GIT_PRIVATE_TOKEN}" ]
then
echo "GIT_PRIVATE_TOKEN unset skipping"
else
echo "GIT_PRIVATE_TOKEN is set configuring git credentials"

git config --global credential.helper store
git config --global --replace-all url."https://token:[email protected]/".insteadOf ssh://[email protected]/
git config --global --add url."https://token:[email protected]/".insteadOf [email protected]
git config --global --add url."https://token:[email protected]/".insteadOf "https://github.com/"

git config --global url."https://ssh:[email protected]/".insteadOf "ssh://[email protected]/"
git config --global url."https://git:[email protected]/".insteadOf "[email protected]:"

Comment on lines +11 to +18
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Address security vulnerabilities in Git credential handling

Several security concerns need to be addressed:

  1. Using --global affects all repositories on the system, which violates the principle of least privilege
  2. The credential helper is set to store, which saves credentials in plain text
  3. The token is stored in plain text in the Git config
  4. The token could be exposed in logs when Git config is listed

Recommended changes:

  1. Use repository-specific configuration instead of global
  2. Use the macOS keychain for secure credential storage
  3. Mask the token in log output
  4. Add cleanup logic to remove credentials after use
-git config --global credential.helper store
+# Use macOS keychain for secure credential storage
+git config credential.helper osxkeychain
+
+# Configure for the specific repository instead of globally
+REPO_DIR="$(git rev-parse --git-dir 2>/dev/null)"
+if [ -z "$REPO_DIR" ]; then
+  echo >&2 "Error: Not in a git repository"
+  exit 1
+fi
+
+# Mask token in logs
+set +x
+
+# Use local config instead of global
-git config --global --replace-all url."https://token:[email protected]/".insteadOf ssh://[email protected]/
-git config --global --add url."https://token:[email protected]/".insteadOf [email protected]
-git config --global --add url."https://token:[email protected]/".insteadOf "https://github.com/"
-git config --global url."https://ssh:[email protected]/".insteadOf "ssh://[email protected]/"
-git config --global url."https://git:[email protected]/".insteadOf "[email protected]:"
+git config url."https://oauth2:[email protected]/".insteadOf ssh://[email protected]/
+git config --add url."https://oauth2:[email protected]/".insteadOf [email protected]
+git config --add url."https://oauth2:[email protected]/".insteadOf "https://github.com/"
+
+# Add cleanup trap
+trap 'git config --remove-section url' EXIT
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
git config --global credential.helper store
git config --global --replace-all url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf ssh://[email protected]/
git config --global --add url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf [email protected]
git config --global --add url."https://token:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "https://github.com/"
git config --global url."https://ssh:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "ssh://[email protected]/"
git config --global url."https://git:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "[email protected]:"
# Use macOS keychain for secure credential storage
git config credential.helper osxkeychain
# Configure for the specific repository instead of globally
REPO_DIR="$(git rev-parse --git-dir 2>/dev/null)"
if [ -z "$REPO_DIR" ]; then
echo >&2 "Error: Not in a git repository"
exit 1
fi
# Mask token in logs
set +x
# Use local config instead of global
git config url."https://oauth2:$GIT_PRIVATE_TOKEN@github.com/".insteadOf ssh://[email protected]/
git config --add url."https://oauth2:$GIT_PRIVATE_TOKEN@github.com/".insteadOf [email protected]
git config --add url."https://oauth2:$GIT_PRIVATE_TOKEN@github.com/".insteadOf "https://github.com/"
# Add cleanup trap
trap 'git config --remove-section url' EXIT

fi

echo "---------- git config --list -------------"
git --no-pager config --list

echo "---------- git config --list --show-origin -------------"
git --no-pager config --list --show-origin
Comment on lines +21 to +25
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Secure the configuration output to prevent token exposure

The current implementation logs the entire Git configuration, which could expose the token in CI logs.

-echo "---------- git config --list -------------"
-git --no-pager config --list
+echo "Verifying Git configuration (sensitive values masked)..."
+git --no-pager config --list | sed -E 's/(oauth2|token):[^@]+@/\1:***@/g'
 
-echo "---------- git config --list --show-origin -------------"
-git --no-pager config --list --show-origin
+echo "Configuration sources:"
+git --no-pager config --list --show-origin | sed -E 's/(oauth2|token):[^@]+@/\1:***@/g'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "---------- git config --list -------------"
git --no-pager config --list
echo "---------- git config --list --show-origin -------------"
git --no-pager config --list --show-origin
echo "Verifying Git configuration (sensitive values masked)..."
git --no-pager config --list | sed -E 's/(oauth2|token):[^@]+@/\1:***@/g'
echo "Configuration sources:"
git --no-pager config --list --show-origin | sed -E 's/(oauth2|token):[^@]+@/\1:***@/g'

Comment on lines +1 to +25
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Git credentials configuration needs attention for security

Based on the verification results:

  1. The script is properly integrated into the CI system through prepare-env.yml command
  2. No credential cleanup mechanism is implemented, which poses a security risk
  3. Script permissions (644) are read-only, which is appropriate for source files
  4. No Unity Package Manager specific configurations were found that would be affected

Recommendations:

  • Add a post-job cleanup step to remove git credentials
  • Consider using CircleCI's built-in credential handling mechanisms instead of storing credentials in git config
🔗 Analysis chain

Verify script integration with CI system and Unity Package Manager

Please verify the following aspects:

  1. Script execution permissions and integration with CI workflows
  2. Proper handling of Unity Package Manager private repository access
  3. Cleanup of credentials after CI job completion
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check script permissions and references in CI config
echo "Checking script permissions and CI configuration..."
fd -t f "set-gitcredential.sh" -x stat -f "%A %N"

# Look for Unity Package Manager configuration
echo "Checking Unity Package Manager configuration..."
fd -t f "manifest.json" -x cat {} \; | grep -A 5 "dependencies"

# Check for credential cleanup in CI workflows
echo "Checking credential cleanup in workflows..."
fd -t f -e yml -e yaml . | xargs grep -l "set-gitcredential"

Length of output: 663


Script:

#!/bin/bash
# Check the content of prepare-env.yml to understand the script usage
echo "Checking prepare-env.yml content..."
cat src/commands/prepare-env.yml

# Try checking script permissions using ls instead of stat
echo "Checking script permissions..."
find . -name "set-gitcredential.sh" -exec ls -l {} \;

# Check for any cleanup or post-job steps in workflows
echo "Checking for cleanup steps..."
rg -A 5 "post-steps|post_build|cleanup" src/commands/prepare-env.yml

Length of output: 4440


Script:

#!/bin/bash
# Check the main set-gitcredential.sh script to understand cleanup handling
echo "Checking main set-gitcredential.sh..."
cat src/scripts/set-gitcredential.sh

# Check if there are any post-job cleanup scripts
echo "Looking for cleanup scripts..."
rg -l "git.*config.*--unset|git.*config.*--remove-section" 

# Check for any Unity package related configurations
echo "Checking Unity package configurations..."
find . -type f -name "*.json" -exec grep -l "packageManager\|registry" {} \;

Length of output: 1004

19 changes: 19 additions & 0 deletions src/scripts/set-gitcredential.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# shellcheck disable=SC2034

readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"

# Import "utils.sh".
eval "$SCRIPT_UTILS"
Comment on lines +1 to +8
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and strict mode for improved robustness

The script setup needs additional safeguards to prevent potential issues:

 #!/usr/bin/env bash
-# shellcheck disable=SC2034
+# shellcheck disable=SC2034  # Justification: Variables are used in evaluated scripts
+
+set -euo pipefail  # Exit on error, undefined vars, and pipe failures
+
+if [ -z "${CIRCLE_WORKING_DIRECTORY:-}" ] || [ -z "${PARAM_PROJECT_PATH:-}" ]; then
+  echo "Error: Required environment variables CIRCLE_WORKING_DIRECTORY and PARAM_PROJECT_PATH must be set"
+  exit 1
+fi
 
 readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
 readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"
 
 # Import "utils.sh".
+if ! eval "$SCRIPT_UTILS"; then
+  echo "Error: Failed to import utils.sh"
+  exit 1
+fi
-eval "$SCRIPT_UTILS"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/usr/bin/env bash
# shellcheck disable=SC2034
readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"
# Import "utils.sh".
eval "$SCRIPT_UTILS"
#!/usr/bin/env bash
# shellcheck disable=SC2034 # Justification: Variables are used in evaluated scripts
set -euo pipefail # Exit on error, undefined vars, and pipe failures
if [ -z "${CIRCLE_WORKING_DIRECTORY:-}" ] || [ -z "${PARAM_PROJECT_PATH:-}" ]; then
echo "Error: Required environment variables CIRCLE_WORKING_DIRECTORY and PARAM_PROJECT_PATH must be set"
exit 1
fi
readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"
# Import "utils.sh".
if ! eval "$SCRIPT_UTILS"; then
echo "Error: Failed to import utils.sh"
exit 1
fi


# Detect host OS.
detect-os

# Expand environment name variable parameters.
readonly git_private_token="${!PARAM_GIT_PRIVATE_TOKEN}"
Comment on lines +10 to +14
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Enhance security for Git token handling

The current token handling implementation needs additional security measures:

 # Detect host OS.
-detect-os
+if ! detect-os; then
+  echo "Error: Failed to detect operating system"
+  exit 1
+fi
 
 # Expand environment name variable parameters.
+if [ -z "${PARAM_GIT_PRIVATE_TOKEN:-}" ]; then
+  echo "Error: PARAM_GIT_PRIVATE_TOKEN environment variable name must be set"
+  exit 1
+fi
+
 readonly git_private_token="${!PARAM_GIT_PRIVATE_TOKEN}"
+
+if [ -z "$git_private_token" ]; then
+  echo "Error: Git private token cannot be empty"
+  exit 1
+fi
+
+# Mask token in debug output
+if [ "${BASH_VERBOSE:-}" = "true" ]; then
+  export PS4='+ $(date "+%Y-%m-%d %H:%M:%S") ${BASH_SOURCE##*/}:${LINENO}: '
+  set -x
+fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Detect host OS.
detect-os
# Expand environment name variable parameters.
readonly git_private_token="${!PARAM_GIT_PRIVATE_TOKEN}"
# Detect host OS.
if ! detect-os; then
echo "Error: Failed to detect operating system"
exit 1
fi
# Expand environment name variable parameters.
if [ -z "${PARAM_GIT_PRIVATE_TOKEN:-}" ]; then
echo "Error: PARAM_GIT_PRIVATE_TOKEN environment variable name must be set"
exit 1
fi
readonly git_private_token="${!PARAM_GIT_PRIVATE_TOKEN}"
if [ -z "$git_private_token" ]; then
echo "Error: Git private token cannot be empty"
exit 1
fi
# Mask token in debug output
if [ "${BASH_VERBOSE:-}" = "true" ]; then
export PS4='+ $(date "+%Y-%m-%d %H:%M:%S") ${BASH_SOURCE##*/}:${LINENO}: '
set -x
fi


if [ "$PLATFORM" = "linux" ]; then eval "$SCRIPT_GIT_CREDENTIAL_LINUX";
elif [ "$PLATFORM" = "macos" ]; then eval "$SCRIPT_GIT_CREDENTIAL_MACOS";
elif [ "$PLATFORM" = "windows" ]; then eval "$SCRIPT_GIT_CREDENTIAL_WINDOWS";
fi
36 changes: 26 additions & 10 deletions src/scripts/windows/return-license.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,35 @@
# shellcheck disable=SC2154

trap_exit() {
local exit_status="$?"

if [ "$exit_status" -ne 0 ]; then
printf '%s\n' 'The script did not complete successfully.'

printf '%s\n' "Removing the container \"$CONTAINER_NAME\"."
docker rm -f "$CONTAINER_NAME" &> /dev/null || true

exit "$exit_status"
fi
local exit_status="$?"
if [ "$exit_status" -ne 0 ]; then
printf '%s\n' 'The script did not complete successfully.'
printf '%s\n' "Removing the container \"$CONTAINER_NAME\"."
docker rm -f "$CONTAINER_NAME" &> /dev/null || true
exit "$exit_status"
fi
}
trap trap_exit EXIT

running_builds=$(docker ps --filter "Name=$CONTAINER_NAME" --format "{{.ID}}")
if [ -z "$running_builds" ]; then
# The build failed before and it killed the host
# Startup so we can return the license
docker run -dit \
--name "$CONTAINER_NAME" \
--env PROJECT_PATH="C:/unity_project" \
--env UNITY_USERNAME="$unity_username" \
--env UNITY_PASSWORD="$unity_password" \
Comment on lines +25 to +27
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add environment variable validation.

The script uses several environment variables but doesn't validate their presence.

Add validation at the beginning of the script:

+# Validate required environment variables
+for var in UNITY_USERNAME UNITY_PASSWORD CONTAINER_NAME GAMECI_EDITOR_VERSION GAMECI_TARGET_PLATFORM; do
+    if [ -z "${!var}" ]; then
+        echo "Error: Required environment variable $var is not set"
+        exit 1
+    fi
+done

Committable suggestion skipped: line range outside the PR's diff.

--volume "C:/Program Files (x86)/Microsoft Visual Studio":"C:/Program Files (x86)/Microsoft Visual Studio" \
--volume "C:/Program Files (x86)/Windows Kits":"C:/Program Files (x86)/Windows Kits" \
--volume "C:/ProgramData/Microsoft/VisualStudio":"C:/ProgramData/Microsoft/VisualStudio" \
"unityci/editor:windows-${GAMECI_EDITOR_VERSION}-${GAMECI_TARGET_PLATFORM}-2" \
powershell
fi
Comment on lines +32 to +33
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incomplete PowerShell command.

The powershell command appears to be incomplete as it doesn't specify any operation to perform.

Either:

  1. Remove this initial PowerShell command if it's not needed, or
  2. Specify the intended PowerShell command to run


set -x
# Return license
docker exec "$CONTAINER_NAME" powershell '& "C:\Program Files\Unity\Hub\Editor\*\Editor\Unity.exe" -returnlicense -batchmode -quit -nographics -username $Env:UNITY_USERNAME -password $Env:UNITY_PASSWORD -logfile | Out-Host'
Expand Down
53 changes: 53 additions & 0 deletions src/scripts/windows/set-gitcredential.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/false
# shellcheck shell=bash
# shellcheck disable=SC2016,SC2154

readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"
Comment on lines +5 to +6
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove unused variable declaration

The unity_project_full_path variable is declared but never used in the script.

 readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
-readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
readonly unity_project_full_path="$base_dir/$PARAM_PROJECT_PATH"
readonly base_dir="${CIRCLE_WORKING_DIRECTORY/\~/$HOME}"
🧰 Tools
🪛 Shellcheck (0.9.0-1)

[warning] 6-6: unity_project_full_path appears unused. Verify use (or export if used externally).

(SC2034)


# Import "utils.sh".
eval "$SCRIPT_UTILS"

# Detect host OS.
detect-os

# Expand environment name variable parameters.
readonly git_private_token="${!PARAM_GIT_PRIVATE_TOKEN}"
readonly CONTAINER_NAME="${CIRCLE_PROJECT_REPONAME}-${CIRCLE_BUILD_NUM}"

trap_exit() {
local exit_status="$?"

if [ "$exit_status" -ne 0 ]; then
printf '%s\n' 'The script did not complete successfully.'

printf '%s\n' "Removing the container \"$CONTAINER_NAME\"."
docker rm -f "$CONTAINER_NAME" &> /dev/null || true

exit "$exit_status"
fi
}
trap trap_exit EXIT


if [ -z "${git_private_token}" ]
then
echo "GIT_PRIVATE_TOKEN unset skipping"
else
echo "GIT_PRIVATE_TOKEN is set configuring git credentials"

docker exec "$CONTAINER_NAME" "git config --global credential.helper store"
docker exec "$CONTAINER_NAME" "git config --global --replace-all url.\"https://token:[email protected]/\".insteadOf ssh://[email protected]/"
docker exec "$CONTAINER_NAME" "git config --global --add url.\"https://token:[email protected]/\".insteadOf [email protected]"
docker exec "$CONTAINER_NAME" "git config --global --add url.\"https://token:[email protected]/\".insteadOf \"https://github.com/\""

docker exec "$CONTAINER_NAME" "git config --global url.\"https://ssh:[email protected]/\".insteadOf \"ssh://[email protected]/\""
docker exec "$CONTAINER_NAME" "git config --global url.\"https://git:[email protected]/\".insteadOf \"[email protected]:\""

Comment on lines +39 to +46
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security and performance improvements needed

Several concerns with the current implementation:

  1. Security: The token is stored in plain text in Git config and might be visible in logs
  2. Performance: Multiple similar Docker exec calls could be combined
  3. Validation: The token format is not validated before use

Consider these improvements:

-    docker exec "$CONTAINER_NAME" "git config --global credential.helper store"
-    docker exec "$CONTAINER_NAME" "git config --global --replace-all url.\"https://token:[email protected]/\".insteadOf ssh://[email protected]/"
-    docker exec "$CONTAINER_NAME" "git config --global --add url.\"https://token:[email protected]/\".insteadOf [email protected]"
-    docker exec "$CONTAINER_NAME" "git config --global --add url.\"https://token:[email protected]/\".insteadOf \"https://github.com/\""
-    
-    docker exec "$CONTAINER_NAME" "git config --global url.\"https://ssh:[email protected]/\".insteadOf \"ssh://[email protected]/\""
-    docker exec "$CONTAINER_NAME" "git config --global url.\"https://git:[email protected]/\".insteadOf \"[email protected]:\""
+    # Validate token format
+    if [[ ! $git_private_token =~ ^gh[ps]_[a-zA-Z0-9]{36}$ ]]; then
+        echo "Error: Invalid GitHub token format"
+        exit 1
+    fi
+    
+    # Combine all git configs into a single command
+    docker exec "$CONTAINER_NAME" /bin/bash -c '
+        git config --global credential.helper store
+        git config --global credential.helper "store --file=/dev/null"  # Don't persist credentials
+        for protocol in "ssh://[email protected]/" "[email protected]" "https://github.com/"; do
+            git config --global --add url."https://oauth:[email protected]/".insteadOf "$protocol"
+        done'

Committable suggestion skipped: line range outside the PR's diff.

fi

echo "---------- git config --list -------------"
docker exec "$CONTAINER_NAME" "git --no-pager config --list"

echo "---------- git config --list --show-origin -------------"
docker exec "$CONTAINER_NAME" "git --no-pager config --list --show-origin"
Comment on lines +49 to +53
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Secure debug output

The current debug output might expose sensitive information including the Git token.

-echo "---------- git config --list -------------"
-docker exec "$CONTAINER_NAME" "git --no-pager config --list"
-
-echo "---------- git config --list --show-origin -------------"
-docker exec "$CONTAINER_NAME" "git --no-pager config --list --show-origin"
+echo "---------- git config (sanitized) -------------"
+docker exec "$CONTAINER_NAME" "git --no-pager config --list | sed -E 's/(oauth|token):[^@]+@/\1:***@/g'"
+
+echo "---------- git config origins -------------"
+docker exec "$CONTAINER_NAME" "git --no-pager config --list --show-origin | grep -v 'url\.'"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "---------- git config --list -------------"
docker exec "$CONTAINER_NAME" "git --no-pager config --list"
echo "---------- git config --list --show-origin -------------"
docker exec "$CONTAINER_NAME" "git --no-pager config --list --show-origin"
echo "---------- git config (sanitized) -------------"
docker exec "$CONTAINER_NAME" "git --no-pager config --list | sed -E 's/(oauth|token):[^@]+@/\1:***@/g'"
echo "---------- git config origins -------------"
docker exec "$CONTAINER_NAME" "git --no-pager config --list --show-origin | grep -v 'url\.'"