#GitHub.gml

1 messages · Page 1 of 1 (latest)

native fable
native fable
#

I'll be adding more stuff to this as time goes on. For now, it can retrieve either a list of releases from a repo or the latest release

native fable
#

I've added functions for all release and release asset endpoints.

native fable
#

I've added a tonne of functions for various issues endpoints, and I have done some maintainence work behind the scenes. Once I have added some other endpoints I will make a pre-release version with documentation

#

If anyone wants some specific endpoint categories fast-tracked, please let me know

near quiver
# native fable If anyone wants some specific endpoint categories fast-tracked, please let me kn...

Any chance your request structure could take in a callback and error (setter functions after request is made) which would automatically be called based on the response? And it would just pass in the body. I'm doing something similar with promise library, however that library only makes the error back optional. Where as here I see there being a benefit to either approach, one is simpler to write, the other is more versatile

#

Thinking something like

var r = GitHub.issue_method()
    .set_callback(func(){})
    .set_errorback(func(){});
#

And obviously if it's undefined you just simply wouldn't call it

native fable
#

Yeah good idea

#

Been looking for a better way to handle receiving the data

#

Noted

#

Also has room for status handling too

#

.status404(function () {})

#

Gets called upon a 404 status code

near quiver
#

I would consider that an error back, but it has its specific uses

#

Maybe if 404 isn't set then default to error back? And if neither are set obviously just don't call anything

#

Personally anything which isn't returning what you're expecting I always consider an error, and pass in all information so the user can decide if they want to try another request or if they would rather fail safely out

native fable
#

That’s a fair point

near quiver
#

also partially unrelated but someone really needs to make an extention for gml which allows for macro overwrites safely.

#

in concept

native fable
#

I dislike the idea of using a macro for an API key here

#

Just because of safety

#

It’s fine for testing but you ideally want to be getting your key from your own web server and using expiring keys and regenerating them every once in a while

#

I have it in a file to test and so that I don’t accidentally commit my auth tokens

#

I’ll also mention this in the docs but I recommend you only use fine-grained tokens

native fable
#

so i got callbacks and errorbacks in

#

tailing the functions likes to crash lmao

native fable
#
request.setCallback(function (_requestBody, _requestObject) {
    if (_requestObject.httpStatus != 204)
    {
        show_debug_message(_requestBody);
    }
    else
    {
        show_debug_message("No data");
    }
});
request.setErrorback(function (_requestBody, _requestObject) {
    if (_requestObject.httpStatus == 404)
    {
        show_debug_message("Object not found.");
    }
    else
    {
        show_debug_message("Some other error.");
    }
});
#

this is the usage

#

it doesnt expect a return value

native fable
#

@near quiver finished all the issues endpoints except for issue dependencies (no idea how its used or what its for)

#

gonna start working on gist now

near quiver
native fable
#

working on gists

native fable
#

oh thats the wrong embed

#

@near quiver first beta release

#

please let me know if you encounter any issues

near quiver
#

Hell yeah!

native fable
#

if you spot anything wrong with the docs let me know, i wrote a script to generate them for me based on the jsdoc comments

native fable
#

github has oauth, im gonna see if i can get oauth working with this library

native fable
#

ive got the basic steps working, need to figure out a simple system to actually request oauth from the user

native fable
#

i got it "working"

#

like it works but its bad

#

and this is the code that makes it work

#

i need to think of a better implementation

proven fjord
#

Oauth is so annoying 🤣

native fable
#

yeah

#

i think ive got a good system in place

#
// Create OAuth
oauth = new GitHubOAuth(_clientID);

// Create auth request
oauthRequest = oauth.requestAuthentication();

// Set the request callback
oauthRequest.setCallback(function (_resultBody, _request)
{
    // Check that the request has made it through
    if (_request.httpStatus == 200)
    {
        // Show debug message to login
        show_debug_message($"Please visit: \"{_resultBody.verification_uri}\" and use the code: \"{_resultBody.user_code}\". This code will expire in {_resultBody.expires_in} seconds.");
        
        // Set our authentication callback (runs when authentication is successful)
        oauth.setAuthenticationCallback(function(_resultBody, _request) {
            show_message(_resultBody);
        });
        
        // Now we poll the authentication
        oauth.pollAuthentication(_resultBody.device_code, _resultBody.interval + 1, 20);
    }
});
#

GitHubOAuth is doing most of the work here

#

there is minimal error checking so I will need to add a bunch in

#

but, if you were using this library would you be happy with this functionality?

near quiver
#

Alub you sound like a teenage girl who just got her first boyfriend, so eager to make people happy. It's fine my guy!

native fable
#

i like active feedback

#

also, feel free to test out the authentication

#

its on the oauth-testing branch

native fable
#

writing docs is a pain in the ass

#

docs for how to authenticate users

proven fjord
deep tide
#

not 100% robust, i didn't handle all the error states, but the basic idea works

native fable
#

Insane work, I did not know that the web flow would work in GM

deep tide
#

the first step is to imagine it is possible and then work backwards from there

native fable
#

Round of applause to you

deep tide
#

it needs a lot of tidying up for it to be acceptable as production code but ... yknow ... i can't be bothered lol

#

do you want a PR for this?

native fable
#

Yeah you can do! Thanks!

#

And tbh, I dunno if I even consider my code production acceptable

deep tide
#

it's pretty good!

#

only thing i saw that exceeded my raised eyebrow threshold was putting the config file under (System)

#

you probably wanna make that more obviously editable

#

everything else is nice and clear and does what it should do, as far as i can tell

native fable
native fable
#

There’s a couple more endpoint categories I want to implement (like another probably 60 actual endpoints, most important being users), a bunch of full scale testing and perhaps some example code, as well as studying the web flow code

#

Once all that’s done I’ll probably consider a v1.0 release

deep tide
#

hypothetically, could this tool be used to automatically list releases and then pull .yymps from GitHub?

#

because this + the ImGui work + an automatic import tool = community package manager

native fable
#

Yeah it can do that right now probably

#

I’d need to fully test the whole process

#

But theoretically, yes

#

It would probably need some sort of index to grab repos from to automatically show a bunch

#

But searching via owner and repo is ez

deep tide
#

oh that's a solveable problem

#

you create an index repo

#

i'd imagine this tool can also read PRs

native fable
#

I haven’t implemented PR endpoints just yet, I can add that to the fast-track though

deep tide
#

please and thank you

#

so then people can PR URLs into a master list. package manager can then have a "safe" and "unsafe" modes where the "safe" mode only looks at the main branch on the repo and the "unsafe" mode also scans the PRs

#

filthy, filthy stuff

native fable
#

That’s certainly something

#

I like the idea

deep tide
#

obvs the import tool is a bit of a challenge but whatever

#

it's just JSON

native fable
#

We love JSON in this household

#

Yeah I have no idea how .yymps’ actually work

#

That would be an interesting problem to solve

deep tide
#

they're .zip files 🙂

native fable
#

Oh wait really?

#

Is it just a .yyz in disguise?

deep tide
#

basically

#

they have a couple extra files

native fable
#

Interesting

#

I don’t know what I was expecting

#

But that is interesting

deep tide
#

having a little poke around now ... looks like a normal project file with bits missing

#

hopefully a merge is as easy as copy-pasting assets

native fable
#

I wonder if stuff like the resource order file and other junk auto updates

deep tide
#

yes it does

#

well, the resource order does

#

you can ignore it

native fable
#

Never really taken a look at how project files work, so I don’t know how assets are indexed

#

All I know is that they use JSON and in gms1.x they used XML(?????)

deep tide
#

yeah GMS1 was bad

#

GMS2.0 was also bad in a different way

#

GMS2.3 is much better

#

i'll let you enjoy the experience of poking around, shan't spoil the fun

native fable
#

I appreciate it thank you, I will peruse once I’m home

native fable
#

back home, working on making some changes to your PR before i merge

#

it works really well

deep tide
#

i was a little surprised it doesn't need port forwarding

#

oooh haven't tried on Android actually

native fable
deep tide
#

nope! doesn't work on Android

#

oh dear

native fable
#

oh no

deep tide
#

there'll be ways around that but i have no idea what they'd be

#

lemme test on Mac real quick

#

yep we're good

#

Linux is probably fine too

native fable
#

thats good

#

hooray

deep tide
#

ah it'll be because the app gets backgrounded

native fable
#

i need to think about how to check for a device-flow timeout

deep tide
#

i'll leave that to you. a timeout will be helpful for both flows

native fable
#

yeah thats for sure

#

i wonder if web-flow has some sort of timeout time like device-flow does?

deep tide
#

nope

#

if you think about it it's just a button on a website

#

that button redirects you to another website

#

(second website being localhost for us)

#

the access token will eventually time out though

native fable
#

thats true, ill look into the lifespan of those tokens

#

though i feel like they probably last a couple days at the minimum

#

added programmer definable HTML for web-flow auth

#

potentially risky business

deep tide
#

you might find you need to handle subsequent GETs from the browser

#

at the moment we're serving one "file" but if you want to do something prettier then you'll need to let the browser request other assets

#

you might also want to change the logic away from using the localhost root to something like http://localhost:52499/please-return-to-game/

#

when the HTTP GET comes in from the browser you'll be able to pick up /please-return-to-game/

#

then subsequent GETs from the browser can be redirected more easily

#

(also you'll want to keep the browser socket open for a while instead of closing it immediately)

#

kinda fun building a basic HTTP server in GM

native fable
#

so many things to consider

#

ill throw all this into an issue and i can deal with them later

near quiver
#

finally got some time to put this to work, should i use the current release or would you prefer i test the oauth @native fable?

native fable
#

the latest release has device-flow authentication

#

you can test with the current main branch commit which has jujus changes and some other stuff

#

all that new stuff is undocumented so youll need to figure it out or ask away here

near quiver
#

sounds good

#

i like un charted domains

native fable
#

im currently working on actual tests that arent just hacked together

near quiver
#

small issue ive already ran into, setters like this are common to be builder structures

#

thought about making a pr for this but its such a small thing

native fable
#

ah okay, its not something ive done before

#

ill sort that out in a minute

near quiver
#

in GitHubIssue what is the difference between assignee and assignees?

native fable
#

im not entirely sure, but the github docs do differentiate the two

#

you can leave either undefined and it wont set those values

near quiver
#

maybe its just old version support

#

oh very nice

native fable
#

oh nice

#

also nice

near quiver
#

nice!

native fable
near quiver
#

while you're at it, its a small thing but helpful

#

when a callback or predicate function is an argument its good practice that the decription states the order of arguments of that function so people dont need to pull up the docs just to make sure if its index, element or element, index

#

looking at you yyg...

#

oh wait it does

native fable
#

ive added them in square brackets to make it more clear

near quiver
#

i actually looked here first i guess i was looking for something else

#

thats a good idea, stand out to the eye a bit more

native fable
#

pushed that too

near quiver
#

i swear i looked though 😭

native fable
#

dont worry about it lol

#

there are so many endpoints ive gotta add

#

anyway, im happy with the current state of the library

#

ofc theres still more to do

near quiver
#

Yeah im very happy this exists, the number of times ive had to write unit tests this will help a lot...

native fable
#

im glad it has its uses

near quiver
#

what would you say is the best way to parse issues to find one with a matching title?

#

just .getIssues()?

native fable
#

that will return all issues in a repo

#

you can filter by "open"

near quiver
#

yeah i see its got some filter options

native fable
#

if the number of open issues is more than 100 youll need to request a second page or more

near quiver
#

and eventually it will 404 yea?

native fable
#

unsure

near quiver
#

on way to find out page=999

#

also i noticed that in some places labels is an array and others its an array-like string

#

GitHubIssue is an array of strings
.getIssues is a string

native fable
#

if youre uploading or updating data, itll be an array

#

if youre getting data itll be an array-like string

#

its just because of the different ways its handled in the API

near quiver
#

ah gotcha

native fable
#

uploading or updating data requires that everything is sent in the body, whereas getting is a optional query parameter

#

i may edit those functions to accept an array or array-like string

#

and deal with it

native fable
#

ill need to figure that stuff out

native fable
#

Yeah, next thing on the list is to parse the response headers and grab some vital information about the response

#

After that I can return to implementing more endpoints

native fable
#

got response headers returning as a struct in _request.responseHeaders

#

adding some helper functions to GitHub to get the last rate limit data

#

.getRateLimitLimit .getRateLimitUsed . getRateLimitRemaining .getRateLimitReset

#

returns back

5000
16
4984
28/11/2025 01:01:41
#

the github docs are not clear on this, but i dont know if the rate limits are per-oauth app / key or per-user that authenticated through said app

near quiver
#

I should consider now before it's a problem how I'll handle caching

native fable
#

you could 100% just store the raw request json as a data file

#

should i have a .cacheResult method in GitHubRequest?

near quiver
#

Nah, because it's likely user preferences on how to cache

#

Like I would want a file, others would want it in memory

native fable
#

yeah thats fair

native fable
#

ive added expire detection in device-flow authentication

#

i dont think that web-flow actually ever times out, but i may add a user-definable time-out time

#

oauth.setAuthenticationTimeoutCallback

#

this callback will fire when an authentication times out either by the max poll attempts being hit or the expire time expires

native fable
#

the web-server now has a shutdown time attached to it

#

if the server needs the be shutdown for any reason, it goes through a time source to delay the shutdown by a user configurable macro

native fable
#

repo content retrieval

native fable
#

I’m gonna take a break from this project for a little while

near quiver
#

you've done great work!

deep tide
#

would you accept PRs if there's something i need and end up making?

native fable
#

Yeah, I’ll keep reviewing PRs and accepting them etc

#

It’s open to all to contribute to

deep tide
#

k

native fable
#

Very intrigued on what you plan to do

deep tide
#

right now i'm mostly interested in auth to get around rate limits

#

if i'm gonna scale up Hotglue then the 60 requests per minute is gonna be a problem

native fable
#

The docs mention a rate limit of 5000 per hour when authenticated, tho I dunno if this is tied to a single user auth token or the client tokens

deep tide
#

indeed

#

without auth it's 60

#

the limit is per IP address

native fable
#

It’s a little annoying to require a user to sign in to actually do useful stuff with hotglue

deep tide
#

not sure what you mean

#

if someone doesn't want to sign in then all that happens is GitHub requests will need to be spaced out

#

everything else is still fine. the API endpoints i'm interested in are, at the moment, all public

native fable
#

Currently at work and it’s a draaaag

near quiver
native fable
#

The simple answer is user authentication via device flow if you don’t wanna try to hide a client secret. Device flow only requires the client ID

#

I need to do more testing with multiple accounts to actually verify if it’s 5000 requests per hour per app or per authenticated user

native fable
#

But 9 time out of 10 most apps that require API access on console do device flow

#

Think YouTube for TV

#

As far as I can tell, the login link is static, so you could easily have a QR code that directs to the login screen

deep tide
#

so it's 5k per person per hour

#

which is plenty

native fable
#

Ah okay cool

deep tide
#

@native fable have you figured out how to view private repos for the auth'd user?

native fable
#

That should just come naturally, as long as the auth perms are set to “repo” I think

#

The auth scope

deep tide
#

tried that, no dice

#

could you give it a go?

native fable
#

Yeah, I’ll be home in about 30 minutes and i can spin up a test for you

native fable
#

yeah, im able to retrieve private repos owned by the currently authenticated user

#

.requestAuthenticationViaWebPage(["repo", "read:user"]); same perms as hotglue

deep tide
#

i'm looking to get a list of repos for the user including private ones

#

the user/repos/ endpoint

#

couldn't get that to work

native fable
deep tide
#

mmok

#

do you have any particular permissions set up for the app?

native fable
#

let me have a look

#

just a bog standard oauth app using webflow

#

are you testing using a github app as opposed to an oauth app?

native fable
#

ill pull hotglue tomorrow evening and have a prod around and see what i can do

deep tide
#

it was indeed a regular GitHub app

#

i will retest tomorrow

native fable
#

Morning

#

Yeah I’ve been using an oauth app for all my testing with webflow authentication

#

After looking at the GitHub app setup page there’s extra perms that can be set that oauth doesn’t have

#

GitHub wants auth to use GitHub app instead of oauth apps and I’m honestly not sure what the benefit is if any at all

#

When I get home later tonight i can take a proper look GitHub apps

deep tide
#

looks like using an OAuth app specifically does the trick

native fable
#

I’m sure that a GitHub app could work but needs to have specific perms attached, unsure but i will test later tonight

deep tide
#

i tried with the Metadata permission but no luck. i think the problem was that i'm using the OAuth flow instead of the GitHub App flow

native fable
#

Interesting

#

I may look into how app flow works, though I’d imagine I couldn’t make it secure enough for production

#

Or be able to get gamemaker to register that a browser wants to focus back to it like how GitHub desktop works

#

And probably other things, but like you said, gotta imagine it works then work backwards

deep tide
#

URI registration is a solved problem for Windows. however, having a running application elegantly pick up subsequent URI invocations isn't solved

deep tide
#

i came up with a workaround a few years ago but it's ugly stuff

native fable
#

Yeah, I wouldn’t imagine there would be an elegant solution

#

I’m curious to see how it actually works for native apps

deep tide
#

.NET basically

#

oh damn it's almost 9 years ago to the day i did URI registration

native fable
#

Interesting

native fable
#

That’s actually something I’m gonna look into

#

Might be able to do it using a c++ extension, hopefully I can get it working on Mac and Linux for a nice cross platform library

deep tide
native fable
#

Yuck

#

I dislike that

#

Linux is somewhat similar to windows but does not require registry edits because there isn’t one for Linux

native fable
#

Alright, researched all 3 desktop OSs URI handling and I have a plan for how to make it work

#

This looks like it’ll be a super fun project, and it is actually useful for actual games

#

mygame://join?room=Y81H7 or something

deep tide
#

Hotglue now has a URI registration solution for Windows

#

feel free to use it as reference, or ignore it entirely

#

whatever you figure out for Mac i will 100% steal

native fable
#

Ooh amazing! Did you get it to work with already running instances?

deep tide
#

yeah

#

so the trick is to spin up a network socket on a particular port when the application runs

#

when you execute the URI, you boot up a new instance of the game. when that new instance is created, that instance will fail to create a socket because of a port conflict

#

you then create a new socket on whatever port is available and send a UDP packet to the original instance and then self-destruct

#

the original instance then receives the URI string via the sent packet and then you can process it

#

you can also do this with saving files on disk as well. i'd prefer to run some of this logic in a batch file but i haven't gotten around to working out the process for that

native fable
#

Oh that’s clean!

#

I was for sure thinking I’d have to deal with multiple instance handling through a DLL

deep tide
#

that network socket thing is a nice trick. it's not flawless, however

#

file saving would be a lot more stable. there will be a way to do it but i've got a meeting with a client in a few minutes so i'll need to figure it out later

native fable
#

Me personally, I hate the idea of saving a file to disk to communicate between processes

#

I agree that it would probably be more stable

#

I wonder how performant checking the hash of a file is

#

My first thought would be check save data for a rando file, check its hash and compare with the last hash, if they’re different, register URI

#

Either that or check if that file exists at all, and delete after reading

deep tide
#

delete after reading is the way forwards

#

fortunately in this situation it's an infrequent operation to trigger the URI

native fable
#

That’s a positive

#

I’m very cautious around a lot of file writing, I’d rather not be the cause to someone’s SSD failing

deep tide
#

Hotglue is a tool that reads and writes hundreds of files per operation

#

i am a criminal, sir

native fable
#

🔫 stick em up

native fable
#

i have an idea on how to get macos URI handling to work, i just cannot test it because i have not paid for my apple developer account yet

#

and thus i cannot build for macos

#

yet

#

the idea is using a build script to add the URL scheme into the apps plist, and resigning the app afterwards

native fable
#

I think I’m gonna work on bug testing all of my current methods for the GitHub API, make sure everything is up to scratch. Then I’ll do a first release (with admittedly not as many endpoints as I’d like)

deep tide
#

good luck!

native fable
#

Thank you kindly

near quiver
#

would it be possible to hook this up to automatically update the ide's version number from github release tags?

#

or you think that would be better off as a pre build script instead?

native fable
#

I just woke up, can you elaborate?

native fable
#

Thanks juju