Gitlab as a Plugin repository


#1

I am in the process of developing a plugin and going to host it on Gitlab. After checking forums and the OctoPrint source code, I couldn't find anything that would indicate Gitlab can be used as a repository for hosting a plugin (code).

It seems only Github is supported. Is that correct?

Thanks! Sacha


#2

That depends on how you define "supported". You can host your plugin where ever you want, all that the plugin manager (and the repository) really needs is some archive URL to use for installing it via pip.

However, if you want to enable automatic updating of your plugin through OctoPrint, the most commonly used version check mechanism you can use for that relies on Github's releases API. I honestly do not know if Gitlab has a similar API, but if it has I would have no problem with merging a PR that adds that as a new version check gitlab_release (and maybe also gitlab_commit?).


#3

Thanks @foosel for the quick reply!

Perhaps worded it not correctly, as I know OctoPrint also can use Bitbucket as a repository :slight_smile:

Gitlab does have a Releases feature similar to that of Github. Not sure how it actually works though but I guess a gitlab_release should be possible. A gitlab_commit equally shouldn't be hard either as Gitlab is just a Git Repository service.

Not sure if I have the time to do a PR, but let me check your documentation and that of Gitlab how that could work.

Thanks again!

Sacha


#4

Mosaic Manufacturing is using GitLab and auto notices come through for that...

https://gitlab.com/mosaic-mfg/canvas-plugin/blob/master/octoprint_canvas/__init__.py#L73

#5

@jneilliii Thanks! That looks like a nice way of doing it.

However your solution is using a custom shell script to check for the latest version. I am considering distributing my plugin, so how do you manage distributing that check script since it is not part of your plugin? (at least I couldn't find it)


#6

Not my solution. But isn't the following doing that part maybe?

https://gitlab.com/mosaic-mfg/canvas-plugin/blob/master/octoprint_canvas/__init__.py#L45

#7

That seems to be getting some other software/code. Not sure what that method is doing as I couldn't find any other reference to it.

This line shows there is a shell command for checking the latest plugin version:
https://gitlab.com/mosaic-mfg/canvas-plugin/blob/master/octoprint_canvas/init.py#L84


#8

I think it's because it's used as a hook when python_updater is the method. I think you'd just update the code to pull the url https://gitlab.com/api/v4/projects/mosaic-mfg%2Fcanvas-plugin/releases (in the case of this plugin) and process the json response comparing it to current version etc. The api documentation for listing the releases in gitlab is over here. I looked at my pi where the plugin is installed and it doesn't have that sh file on it where it's listed as being, so maybe there is some other magic they are doing. Maybe just using their own server to control the release of the version versus using the gitlab release mechanism and checking against that.


#9

This might work, no guarantees....you would replace the parts to point to your gitlab repo, etc. You'll have to make sure you import both requests and LooseVersion at the beginning of your init file. What I'm not 100% sure on is if the pip declaration will replace the tokens in the url or not, but if not you could just force it to the main zip download url of your master repo.

	def get_latest(self, target, check, full_data=False, online=True):
		request_url = "https://gitlab.com/api/v4/projects/{user}%2F{repo}/releases".format(check)
		resp = requests.get(request_url)
		version_data = resp.json()
		version = version_data[0]["name"]
		current_version = check.get("current")
		information = dict(
			local=dict(
				name=current_version,
				value=current_version,
			),
			remote=dict(
				name=version,
				value=version
			)
		)
		self._logger.info("current version: %s" % current_version)
		self._logger.info("remote version: %s" % version)
		needs_update = LooseVersion(current_version) < LooseVersion(version)
		self._logger.info("needs update: %s" % needs_update)

		return information, not needs_update

	def get_update_information(self):
		return dict(
			canvas=dict(
				displayName="Canvas Plugin",
				displayVersion=self._plugin_version,
				current=self._plugin_version,
				python_checker=self,
				type="python_checker",
				user="mosaic-mfg",
				repo="canvas-plugin"
				pip="https://gitlab.com/mosaic-mfg/canvas-plugin/-/archive/{target_version}/canvas-plugin-{target_version}.zip"
			)
		)

#10

@jneilliii Thanks for the example! Pretty clear now. I will give this a try.

Cheers! Sacha