add commentary and (unused) check for token applicability
This commit is contained in:
parent
3b195a9eb6
commit
f4d66203b9
2 changed files with 90 additions and 4 deletions
23
README.md
23
README.md
|
@ -24,10 +24,10 @@ zig build
|
|||
2. Run the application:
|
||||
|
||||
```bash
|
||||
./zig-out/bin/release-tracker config.json
|
||||
./zig-out/bin/release-tracker config.json [output filename]
|
||||
```
|
||||
|
||||
3. The RSS feed will be generated as `releases.xml`
|
||||
3. The RSS feed will be generated as `releases.xml` by default
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -50,11 +50,28 @@ Create a `config.json` file with your API tokens:
|
|||
|
||||
### API Token Setup
|
||||
|
||||
- **GitHub**: Create a Personal Access Token with `public_repo` and `user` scopes
|
||||
- **GitHub**: Create a Personal Access Token with and `user:read` scope. Classic is preferred (see note)
|
||||
- **GitLab**: Create a Personal Access Token with `read_api` scope
|
||||
- **Codeberg**: Create an Access Token in your account settings
|
||||
- **SourceHut**: No token required for public repositories. Specify repositories to track in the configuration.
|
||||
|
||||
Note on GitHub PATs. Some GitHub orgs will place additional restrictions on
|
||||
PATs. If your token does not align with those policies, the GitHub stars API
|
||||
will **silently discard** repos from that org. The only way to tell something
|
||||
is off is by detecting the starred repositories count at
|
||||
https://github.com/<username>?tab=stars is more than what is reported in the
|
||||
application output.
|
||||
|
||||
There is a `checkForInaccessibleRepos` function in the GitHub provider that
|
||||
can detect this, but is limited to the `aws` organization, which may or may
|
||||
not apply in all situations. For this reason, it is included in the code, but
|
||||
disabled. If needed, uncomment the call and choose a repo from your enterprise
|
||||
of choice.
|
||||
|
||||
These org policies do not seem to effect classic tokens, so the best approach
|
||||
with GitHub is to create and use a classic token instead of the new fine-grained
|
||||
tokens.
|
||||
|
||||
## Testing
|
||||
|
||||
Run the test suite:
|
||||
|
|
|
@ -54,6 +54,10 @@ pub fn fetchReleases(self: *Self, allocator: Allocator) !ArrayList(Release) {
|
|||
|
||||
const starred_duration: u64 = @intCast(starred_end_time - starred_start_time);
|
||||
std.log.debug("GitHub: Found {} starred repositories in {}ms", .{ starred_repos.items.len, starred_duration });
|
||||
|
||||
// Check for potentially inaccessible repositories due to enterprise policies
|
||||
// try checkForInaccessibleRepos(allocator, &client, self.token, starred_repos.items);
|
||||
|
||||
std.log.debug("GitHub: Processing {} starred repositories with thread pool...", .{starred_repos.items.len});
|
||||
|
||||
const thread_start_time = std.time.milliTimestamp();
|
||||
|
@ -423,6 +427,71 @@ fn compareReleasesByDate(context: void, a: Release, b: Release) bool {
|
|||
return a.published_at > b.published_at;
|
||||
}
|
||||
|
||||
fn checkForInaccessibleRepos(allocator: Allocator, client: *http.Client, token: []const u8, starred_repos: [][]const u8) !void {
|
||||
const is_test = @import("builtin").is_test;
|
||||
if (is_test) return; // Skip in tests
|
||||
|
||||
// List of repositories that are commonly affected by enterprise policies
|
||||
const problematic_repos = [_][]const u8{
|
||||
"aws/language-server-runtimes",
|
||||
"aws/aws-cli",
|
||||
"aws/aws-sdk-js",
|
||||
"aws/aws-cdk",
|
||||
};
|
||||
|
||||
const auth_header = try std.fmt.allocPrint(allocator, "Bearer {s}", .{token});
|
||||
defer allocator.free(auth_header);
|
||||
|
||||
for (problematic_repos) |repo| {
|
||||
// Check if this repo is in our starred list
|
||||
var found_in_starred = false;
|
||||
for (starred_repos) |starred_repo| {
|
||||
if (std.mem.eql(u8, starred_repo, repo)) {
|
||||
found_in_starred = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_in_starred) {
|
||||
// Check if we can access this repository directly to see if it's a policy issue
|
||||
const check_url = try std.fmt.allocPrint(allocator, "https://api.github.com/user/starred/{s}", .{repo});
|
||||
defer allocator.free(check_url);
|
||||
|
||||
const uri = std.Uri.parse(check_url) catch continue;
|
||||
|
||||
var server_header_buffer: [16 * 1024]u8 = undefined;
|
||||
var req = client.open(.GET, uri, .{
|
||||
.server_header_buffer = &server_header_buffer,
|
||||
.extra_headers = &.{
|
||||
.{ .name = "Authorization", .value = auth_header },
|
||||
.{ .name = "Accept", .value = "application/vnd.github.v3+json" },
|
||||
.{ .name = "User-Agent", .value = "release-tracker/1.0" },
|
||||
},
|
||||
}) catch continue;
|
||||
defer req.deinit();
|
||||
|
||||
req.send() catch continue;
|
||||
req.wait() catch continue;
|
||||
|
||||
if (req.response.status == .forbidden) {
|
||||
// Try to read the error response for more details
|
||||
const error_body = req.reader().readAllAlloc(allocator, 4096) catch "";
|
||||
defer if (error_body.len > 0) allocator.free(error_body);
|
||||
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
if (std.mem.indexOf(u8, error_body, "enterprise") != null or
|
||||
std.mem.indexOf(u8, error_body, "personal access token") != null or
|
||||
std.mem.indexOf(u8, error_body, "fine-grained") != null)
|
||||
{
|
||||
stderr.print("GitHub: Repository '{s}' may be starred but is inaccessible due to enterprise policies: {s}\n", .{ repo, error_body }) catch {};
|
||||
} else {
|
||||
stderr.print("GitHub: Repository '{s}' is not accessible (HTTP 403): {s}\n", .{ repo, error_body }) catch {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "github provider" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue