Development Tutorials PHP & MySQL
Gitlab is a great alternative to Github or BitBucket, they offer free private and public repositories which is great when working with a team, I’ve recently started using Gitlab for a private project, where I need to download private repositories to the project server and extract their contents.
Github offers a great API http://doc.gitlab.com/ee/api/
To get started with their API you need a private token. Your token can be found inside your account page https://gitlab.com/profile/account
All API requests require authentication. You need to pass a private_token parameter via query string or header. If passed as a header, the header name must be PRIVATE-TOKEN (uppercase and with a dash instead of an underscore). You can find or reset your private token in your account page (/profile/account).
To use the API the token must be passed in all requests, for get requests its as simple as ?private_token=yourtoken
In order to download the repository it’s id is needed. A list of repositories can be seen by going to
https://gitlab.com/api/v3/projects?private_token=yourtoken
Other options can be passed such as looking at private repositories only and ordering them by name:
https://gitlab.com/api/v3/projects?private_token=yourtoken&visibility=private&order_by=name
This will give you a list of projects:
[
{
"id": 4,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"tag_list": [
"example",
"disapora client"
],
"owner": {
"id": 3,
"name": "Diaspora",
"created_at": "2013-09-30T13: 46: 02Z"
},
"name": "Diaspora Client",
"name_with_namespace": "Diaspora / Diaspora Client",
"path": "diaspora-client",
"path_with_namespace": "diaspora/diaspora-client",
"issues_enabled": true,
"open_issues_count": 1,
"merge_requests_enabled": true,
"builds_enabled": true,
"wiki_enabled": true,
"snippets_enabled": false,
"created_at": "2013-09-30T13: 46: 02Z",
"last_activity_at": "2013-09-30T13: 46: 02Z",
"creator_id": 3,
"namespace": {
"created_at": "2013-09-30T13: 46: 02Z",
"description": "",
"id": 3,
"name": "Diaspora",
"owner_id": 1,
"path": "diaspora",
"updated_at": "2013-09-30T13: 46: 02Z"
},
"archived": false,
"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
"shared_runners_enabled": true,
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"public_builds": true
},
{
"id": 6,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:brightbox/puppet.git",
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"tag_list": [
"example",
"puppet"
],
"owner": {
"id": 4,
"name": "Brightbox",
"created_at": "2013-09-30T13:46:02Z"
},
"name": "Puppet",
"name_with_namespace": "Brightbox / Puppet",
"path": "puppet",
"path_with_namespace": "brightbox/puppet",
"issues_enabled": true,
"open_issues_count": 1,
"merge_requests_enabled": true,
"builds_enabled": true,
"wiki_enabled": true,
"snippets_enabled": false,
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
"created_at": "2013-09-30T13:46:02Z",
"description": "",
"id": 4,
"name": "Brightbox",
"owner_id": 1,
"path": "brightbox",
"updated_at": "2013-09-30T13:46:02Z"
},
"permissions": {
"project_access": {
"access_level": 10,
"notification_level": 3
},
"group_access": {
"access_level": 50,
"notification_level": 3
}
},
"archived": false,
"avatar_url": null,
"shared_runners_enabled": true,
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"public_builds": true
}
]
The id is what’s important here so make a note of the id for the project that will be used.
To then download the repository pass the id to /projects/:id so /projects/6 followed by your token:
https://gitlab.com/api/v3/projects/6/repository/archive?private_token=yourtoken
Now to use this in a php script:
Set a name for the local tar.gz file to be used, I use temp as it will be deleted once finished.
Next use file_get_contents to download the file from the api and save it to $name notice the .tar.gz on the end.
//set file name
$name = 'temp';
//download contents file the above filename with .tar.gz appended.
//Remember to replace your id and token
file_put_contents($name.'.tar.gz', fopen("https://gitlab.com/api/v3/projects/id/repository/archive?private_token=your_token_here", 'r'));
Next unpack the .tar.gz file this creates a .tar file so unpack that too.
// decompress from gz
$p = new \PharData($zipname.'.tar.gz');
$p->decompress(); // creates files.tar
// unarchive from the tar
$phar = new \PharData($zipname.'.tar');
$phar->extractTo('folder/to/extract/to/', null, true); // extract all files, and overwrite
The packed files are no longer needed to delete them.
//delete temp.tar.gz
if (file_exists($zipname.'.tar.gz')) {
unlink($zipname.'.tar.gz');
}
//delete temp.tar
if (file_exists($zipname.'.tar')) {
unlink($zipname.'.tar');
}
This leaves a folder with a name similar to this: projectname-master- followed by a long string, to have the folder only containing the fodler name ie projectname:
$dirs = glob('folder/files/extracted/to/*');
//loop through them
foreach ($dirs as $dir) {
//if is a directory
if (is_dir($dir)) {
//explode the name where there is a -
$parts = explode('-', $dir);
//if the name does not exist ie there is no projectname only projectname-master-3r3rr4
if (!file_exists($parts[0])) {
//rename to lose everything after and including the -
rename($dir, $parts[0]);
}
}
}
//set file name
$name = 'temp';
//download contents file the above filename with .tar.gz appended.
//Remember to replace your id and token
file_put_contents($name.'.tar.gz', fopen("https://gitlab.com/api/v3/projects/id/repository/archive?private_token=your_token_here", 'r'));
// decompress from gz
$p = new \PharData($zipname.'.tar.gz');
$p->decompress(); // creates files.tar
// unarchive from the tar
$phar = new \PharData($zipname.'.tar');
$phar->extractTo('folder/to/extract/to/', null, true); // extract all files, and overwrite
//delete temp.tar.gz
if (file_exists($zipname.'.tar.gz')) {
unlink($zipname.'.tar.gz');
}
//delete temp.tar
if (file_exists($zipname.'.tar')) {
unlink($zipname.'.tar');
}
$dirs = glob('folder/files/extracted/to/*');
//loop through them
foreach ($dirs as $dir) {
//if is a directory
if (is_dir($dir)) {
//explode the name where there is a -
$parts = explode('-', $dir);
//if the name does not exist ie there is no projectname only projectname-master-3r3rr4
if (!file_exists($parts[0])) {
//rename to lose everything after and including the -
rename($dir, $parts[0]);
}
}
}
Subscribe to my newsletter for the latest updates on my books and digital products.
Find posts, tutorials, and resources quickly.
Subscribe to my newsletter for the latest updates on my books and digital products.