Skip to content

[TT-17817] Keeping Tyk Dependencies Up To Date - Building The Alerting and Update Mechanism - #148

Draft
buraksezer wants to merge 1 commit into
mainfrom
feat/TT-17817/eol-notifier
Draft

[TT-17817] Keeping Tyk Dependencies Up To Date - Building The Alerting and Update Mechanism#148
buraksezer wants to merge 1 commit into
mainfrom
feat/TT-17817/eol-notifier

Conversation

@buraksezer

Copy link
Copy Markdown
Contributor

@probelabs

probelabs Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

This PR introduces a new automated system for monitoring and alerting on the end-of-life (EoL) dates of key dependencies used by Tyk. The core of this change is a new GitHub Action and workflow named "EoL Notifier".

Files Changed Analysis

This is a significant feature addition, comprising 26 new or modified files with approximately 3,700 lines of new code and no deletions. The changes are primarily centered around the new eol-notifier/ directory, which contains a self-contained Go application, and new GitHub workflow configurations.

  • eol-notifier/: A new Go application that implements the core logic for fetching dependency data, detecting EoL dates, and sending alerts.
  • .github/workflows/eol-notifier.yaml: A new scheduled workflow that runs daily to trigger the notifier.
  • .github/eol-notifier/dependencies.yaml: A new configuration file listing the dependencies to be tracked.
  • docs/workflows/eol-notifier.md: Documentation for the new workflow.
  • .github/workflows/ci-test.yml: Updated to include a test job for the new Go application.
  • .github/.dependabot.yml: Updated to manage dependencies for the new Go module.

Architecture & Impact Assessment

What this PR accomplishes:
This PR automates the process of tracking dependency lifecycles. It proactively alerts the engineering team via Slack when a dependency is nearing its end-of-life or when a new version is released. This helps mitigate security risks from unsupported software and aids in planning necessary upgrades.

Key technical changes introduced:

  • A new daily scheduled GitHub workflow is introduced.
  • A Go-based composite GitHub Action is created to encapsulate the notification logic. This action is responsible for:
    • Reading the dependency configuration from dependencies.yaml.
    • Fetching lifecycle data from the endoflife.date API.
    • Comparing current data against a stored state to identify new versions.
    • Sending formatted alerts to a configured Slack webhook.
  • A state-management mechanism is implemented using a dedicated Git branch (eol-notifier-state) to persist the list of seen dependency versions between workflow runs. This avoids committing operational state to the main branch.

Affected system components:

  • GitHub Actions & CI/CD: Introduces a new scheduled workflow and modifies the existing CI test suite.
  • Dependency Management Process: Creates a new, automated monitoring and alerting component that will feed into the team's existing dependency management and upgrade planning processes.

System Flow:

graph TD
    A[Schedule: Daily] --> B{eol-notifier.yaml Workflow};
    B --> C["Restore State from 'eol-notifier-state' branch"];
    B --> D[Run Notifier Action];
    D --> E[Read dependencies.yaml];
    D --> F[Fetch Data from endoflife.date API];
    F --> G{Compare & Detect Alerts};
    G -- "EoL / New Version" --> H[Format Slack Message];
    H --> I[Post to Slack];
    G --> J[Update State];
    J --> K["Commit State to 'eol-notifier-state' branch"];
Loading

Scope Discovery & Context Expansion

This PR establishes a new, robust pattern for stateful, scheduled automation within the repository. The use of a separate Git branch for state management is a key architectural choice that isolates operational data from the main codebase and could be adopted for other automated tasks.

The immediate impact is confined to developer alerting and awareness, with no direct changes to production services. However, the alerts generated by this system are intended to trigger manual engineering work, such as creating tickets for dependency upgrades and getting commercial approval for version changes, as outlined in the new documentation.

Metadata
  • Review Effort: 4 / 5
  • Primary Label: feature

Powered by Visor from Probelabs

Last updated: 2026-08-01T19:51:35.826Z | Triggered by: pr_opened | Commit: 8cd2870

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs

probelabs Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Security Issues (1)

Severity Location Issue
🟡 Warning eol-notifier/cmd/notifier/slack.go:70
The Slack webhook URL, which is a secret, may be leaked to logs upon network errors. The error returned by `http.Client.Do` can include the full request URL in its message. This error is then wrapped and eventually logged by `main.go`, potentially exposing the webhook URL in the GitHub Actions logs. While GitHub Actions has secret masking, it is not foolproof and should not be the only line of defense.
💡 SuggestionDo not wrap the raw network error directly. Instead, return a more generic error message that omits potentially sensitive details from the original error, to prevent the webhook URL from being logged.
🔧 Suggested Fix
if err != nil {
    // The error from http.Client.Do may contain the full webhook URL, so we
    // return a generic error to avoid logging the secret.
    return fmt.Errorf("failed to post to Slack: network error")
}

Architecture Issues (1)

Severity Location Issue
🟡 Warning .github/workflows/eol-notifier.yaml:71-100
The mechanism for recording state uses low-level git plumbing commands (`hash-object`, `mktree`, `commit-tree`) to build and push a commit without a local checkout. While this is an efficient and technically sound approach that avoids a full checkout, it introduces significant complexity into the workflow file. This complexity could pose a maintainability challenge for team members who are not deeply familiar with these specific git commands, making future modifications or debugging more difficult.
💡 SuggestionFor long-term maintainability, consider abstracting this git logic. One option is to move the script into a separate file (e.g., in a `scripts/` directory) and call it from the workflow. An even cleaner approach would be to create a dedicated composite action (e.g., `.github/actions/commit-file`) that encapsulates this logic, taking inputs like file path, branch, and commit message. This would make the main `eol-notifier.yaml` workflow much simpler and more declarative, improving readability and maintainability.

Performance Issues (2)

Severity Location Issue
🟡 Warning eol-notifier/cmd/notifier/lifecycle.go:231-247
The `dependenciesFor` function is repeatedly called from within the nested loops of `detectAlerts`, causing it to iterate over the entire dependency list for each release of every product. This leads to an inefficient O(P * R * D) complexity, where P is products, R is releases, and D is dependencies. While not critical at the current scale, this is a suboptimal algorithm that will degrade performance as the number of configured dependencies grows.
💡 SuggestionOptimize the alert detection logic by pre-processing the dependency configuration. Before entering the main loops in `detectAlerts`, create a map that groups dependencies by their product slug (e.g., `map[string][]Dependency`). This allows for an efficient O(1) lookup of relevant dependencies for each product inside the loop, rather than a full O(D) scan, improving the overall algorithm.
🟡 Warning eol-notifier/cmd/notifier/main.go:154-171
The `fetchProducts` function makes sequential network requests to the endoflife.date API within a `for` loop. Each request introduces network latency, and executing them one by one can lead to a significant total execution time, especially if the number of unique products to check increases or the API response time is slow. This can be improved by executing the requests concurrently.
💡 SuggestionTo improve performance, parallelize the API calls in `fetchProducts`. Use goroutines to initiate each `client.FetchProduct` call concurrently and a `sync.WaitGroup` to wait for all requests to complete. This will allow the I/O operations to happen in parallel, significantly reducing the total time spent waiting for network responses.

Powered by Visor from Probelabs

Last updated: 2026-08-01T19:51:09.549Z | Triggered by: pr_opened | Commit: 8cd2870

💡 TIP: You can chat with Visor using /visor ask <your question>

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.

1 participant