Skip to content

Conversation

@gjarzebak95
Copy link

@gjarzebak95 gjarzebak95 commented Jan 9, 2026

Fixes Google to GitHub user synchronisation issues identified in SA-675.


Fix 1: Archived Google users receiving GitHub invites

Problem: Users marked as archived or suspended in Google Workspace were still being detected as active. If they had a GitHub ID in their profile, the sync would send them an org invite.

Root cause: The Google Directory API query wasn't filtering out suspended/archived users, and the application had no secondary check.

Solution:

File Line Change
src/google.ts 34 Added query: 'isSuspended=false' to Google API request to filter suspended users at source
src/google.ts 35 Added suspended,archived to fields parameter to retrieve these flags
src/google.ts 47 Added .filter((user) => !user.suspended && !user.archived) as secondary filter for archived users (Google API doesn't support isArchived query param)

Why both filters? Google API supports isSuspended query filter but not isArchived. The API-level filter reduces data transfer, the application-level filter catches archived users.

Tests: tests/google.spec.ts lines 73-84


Fix 2: Pipeline failure on successful membership changes

Problem: When the sync detected a mismatch and successfully added/removed users, it still exited with non-zero code, causing pipeline failures even though the operation succeeded.

Root cause: Original logic: exitCode = (anyMismatch) ? nonZero : 0 — any detected difference triggered failure exit, regardless of whether it was resolved.

Solution:

File Line Change
index.ts 16 Added unfixedMismatch flag, only set true when mismatch exists AND corresponding action (ADD_USERS/REMOVE_USERS) is disabled
index.ts 54 Changed exit logic to: exitCode = (unfixedMismatch || hasErrors) ? nonZero : 0

New behaviour:

  • Mismatch detected + changes applied successfully → exit 0
  • Mismatch detected + action disabled (dry-run) → exit non-zero
  • Mismatch detected + errors during changes → exit non-zero

Tests: tests/index.spec.ts lines 40-52


Fix 3: Silent failure on org capacity limit

Problem: When GitHub org hit max user count, the API returned 422 error which was not caught or surfaced. Sync appeared to succeed but users weren't actually added.

Root cause: No try/catch around GitHub API calls, no error aggregation or reporting.

Solution:

File Line Change
src/github.ts 5-16 Added OperationError and OperationResult interfaces to track individual operation outcomes
src/github.ts 78-99 Wrapped createInvitation in try/catch, parse error status codes
src/github.ts 91 422 errors get message: "Validation failed: ... (user may already be invited, or org is at max capacity)"
src/github.ts 93-95 Also handle 404 (user not found) and 403 (rate limit/permission)
index.ts 45-50 Display error summary at end: --- ERRORS SUMMARY --- with each failed operation

Error visibility: All errors collected during run, summarised at end with operation type, username, and error message.

Tests: tests/github.spec.ts lines 109-130 ("handles 422 error (org full)")


Fix 4: No Slack notifications

Problem: No way to know when membership changes occurred or when errors happened without checking pipeline logs.

Solution:

File Line Change
src/slack.ts (new file) 141-line module for Slack webhook notifications
src/config.ts 30-42 Config getters for Slack options
action.yml 44-57 Input parameters for Slack configuration
index.ts 52 Call notifySlack() after operations complete

Configuration options:

Input Default Behaviour
slack-webhook-url (none) Required for any notifications
slack-notify-on-error true Send notification when errors occur
slack-notify-on-change false Send notification when users added/removed
slack-notify-always false Send notification on every run

Message format: Slack Block Kit with header, lists of added/removed users, error details if any.

Tests: tests/slack.spec.ts (full test suite)


Fix 5: Outdated libraries

Problem: Node.js 15.x EOL, GitHub Actions v3 deprecated (actions/cache v3.3.1 blocked by GitHub Dec 2024).

Solution:

File Change
.nvmrc 16.20.018.20.0
.github/workflows/ci.yml:10 Node 15.12.018.20.0
.github/workflows/ci.yml:17 actions/checkout v3.5.2 → v4.2.2
.github/workflows/ci.yml:19 actions/setup-node v3.6.0 → v4.1.0
.github/workflows/ci.yml:23 actions/cache v3.3.1 → v4.2.3

Deferred: npm package updates (octokit, jest, eslint) have breaking API changes — recommend separate PR with dedicated testing.


Test Coverage Summary

Area Test File Key Tests
Suspended/archived filtering google.spec.ts "filters out suspended users", "filters out archived users"
Exit code behaviour index.spec.ts "exit with 0 when mismatch is fixed", "exit with 122 when only add enabled but remove mismatch exists"
Error handling github.spec.ts "handles 422 error (org full)", "handles 403 error (rate limit)", "handles 404 error"
Slack notifications slack.spec.ts Trigger conditions, message formatting, HTTP handling

How to Test

  1. Archived user filtering: Create test Google user, archive them, verify they don't appear in sync
  2. Exit codes: Run with ADD_USERS=true, verify exit 0 when users added successfully
  3. Error surfacing: Temporarily hit org limit or use invalid user, verify error summary appears
  4. Slack: Configure webhook URL, run sync, verify notification received

Next Steps After Merge

1. Create release & build Docker image

# In appvia/githubUserManager repo
# Create release v1.0.6 — CI will auto-build Docker image
gh release create v1.0.6 --title "v1.0.6" --notes "SA-675: Sync fixes, Slack notifications, Node 18"

Docker image will be pushed to: docker.pkg.github.com/appvia/githubusermanager/githubusermanager:v1.0.6

2. Update action.yml to use new image

Change line 73 in action.yml:
- docker.pkg.github.com/appvia/githubusermanager/githubusermanager:v1.0.5
+ docker.pkg.github.com/appvia/githubusermanager/githubusermanager:v1.0.6

3. Configure Slack (optional)

In consuming workflow, add:
- uses: appvia/githubUserManager@v1.0.6
  with:
    # ... existing inputs ...
    slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
    slack-notify-on-change: 'true'

- Add query parameter to filter suspended users at API level
- Add secondary filter in formatUserList for archived users
- Include suspended/archived fields in API response
- Add tests for suspended/archived user filtering
Previously, any mismatch would trigger non-zero exit even when
ADD_USERS and REMOVE_USERS were enabled and changes were made.
Now only exits non-zero when mismatch exists AND changes were
not configured to be applied (dry-run mode).
- Add OperationError interface to track individual failures
- Add OperationResult interface to collect successes and errors
- Wrap GitHub API calls in try/catch blocks
- Parse specific error codes (422, 403, 404) with helpful messages
- Surface max user count errors (422) clearly
- Collect all errors and display summary at end of run
- Exit with non-zero when errors occur
- Add slack.ts module with notification functionality
- Add config options: SLACK_WEBHOOK_URL, SLACK_NOTIFY_ON_ERROR,
  SLACK_NOTIFY_ON_CHANGE, SLACK_NOTIFY_ALWAYS
- Update action.yml with new Slack inputs
- Send notifications on errors (default), changes (opt-in), or always
- Format messages with users added, removed, and any errors
Node 15.12.0 was EOL. Updated to Node 18 LTS for security and
compatibility. Major npm package updates (octokit, jest, eslint)
require careful testing due to breaking API changes and should
be addressed in a follow-up PR.
- Remove unused slack import from index.spec.ts
- Remove unused consoleSpy variable from slack.spec.ts
- Add eslint-disable comments for necessary any types in test mocks
- actions/checkout: v3.5.2 → v4.2.2
- actions/setup-node: v3.6.0 → v4.1.0
- actions/cache: v3.3.1 → v4.2.3

Fixes CI failure due to deprecated actions/cache version being blocked
by GitHub as of Dec 2024.
@gjarzebak95 gjarzebak95 changed the title Feat/sa 675 google GitHub sync v2 fix(SA-675): Google GitHub sync fixes Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants