mirror of
https://git.cloudron.io/cloudron/gitea-app
synced 2025-09-25 22:47:24 +00:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e7671bd3f2 | ||
|
32cc8175e5 | ||
|
534e4884b4 | ||
|
6e1f363b88 | ||
|
3eb57f2c07 | ||
|
b16095eef5 | ||
|
18b3ae6bc2 | ||
|
fbf8e5f953 | ||
|
106e65df9e | ||
|
1b629265fa | ||
|
f9949c11a3 | ||
|
a7e693c4ed | ||
|
b00d2aced2 | ||
|
c2419ba46c | ||
|
b39e1850d7 | ||
|
4d37e33eee | ||
|
b86f9c7a20 | ||
|
7fd766b348 | ||
|
525327c150 | ||
|
bc658da61e | ||
|
25f206ccdb | ||
|
d3553de1a6 | ||
|
99379fdbb3 | ||
|
21a9fccd60 |
107
CHANGELOG
107
CHANGELOG
@@ -67,3 +67,110 @@
|
|||||||
* Fix issue list branch link broken (#3061) (#3070)
|
* Fix issue list branch link broken (#3061) (#3070)
|
||||||
* Fix missing password length check when change password (#3039) (#3071)
|
* Fix missing password length check when change password (#3039) (#3071)
|
||||||
|
|
||||||
|
[1.3.1]
|
||||||
|
* Update Gitea to 1.3.2
|
||||||
|
* Fix run web with -p push failed (#3154) (#3179)
|
||||||
|
* Fix source download link when no code unit allowed (#3166) (#3169)
|
||||||
|
* Allow adding collaborators with (fullname) (#3103) (#3168)
|
||||||
|
* Fix repo links (#3093) (#3163)
|
||||||
|
* Fix Uninitialized variable in ParsePatch (#3156) (#3162)
|
||||||
|
* Fix migration order v1.3 (#3157)
|
||||||
|
* Fix avatar URLs (#3069) (#3143)
|
||||||
|
|
||||||
|
[1.4.0]
|
||||||
|
* Fix email sending (use SMTPS)
|
||||||
|
|
||||||
|
[1.4.1]
|
||||||
|
* Update Gitea to 1.3.3
|
||||||
|
* Security fixes
|
||||||
|
* Fix escaping changed title in comments (#3530) (#3535)
|
||||||
|
* Escape search query display (#3486) (#3489)
|
||||||
|
* Bug fixes
|
||||||
|
* Fix repo-transfer-and-team-repo-count bug (#3241) (#3244)
|
||||||
|
* Open external tracker in blank window, consistently with wiki (#3227) (#3228)
|
||||||
|
* Change SSL Mode from checkbox to string in admin page (#3208) (#3211)
|
||||||
|
|
||||||
|
[1.5.0]
|
||||||
|
* Update Gitea to 1.4.0
|
||||||
|
|
||||||
|
[1.5.1]
|
||||||
|
* Update Gitea to 1.4.1
|
||||||
|
* Add “error” as reserved username (#3882) (#3886)
|
||||||
|
* Do not allow inactive users to access repositories using private key (#3887) (#3889)
|
||||||
|
* Fix path cleanup in file editor, when initilizing new repository and LFS oids (#3871) (#3873)
|
||||||
|
* Remove unnecessary allowed safe HTML (#3778) (#3779)
|
||||||
|
* Correctly check http git access rights for reverse proxy authorized users (#3721) (#3743)
|
||||||
|
* Fix to use only needed columns from tables to get repository git paths (#3870) (#3883)
|
||||||
|
* Fix GPG expire time display when time is zero (#3584) (#3884)
|
||||||
|
* Fix to update only issue last update time when adding a comment (#3855) (#3860)
|
||||||
|
* Fix repository star count after deleting user (#3781) (#3783)
|
||||||
|
* Use the active branch for the code tab (#3720) (#3776)
|
||||||
|
* Set default branch name on first push (#3715) (#3723)
|
||||||
|
* Show clipboard button if disable HTTP of git protocol (#3773) (#3774)
|
||||||
|
|
||||||
|
[1.5.2]
|
||||||
|
* Update Gitea to 1.4.2
|
||||||
|
* Adjust z-index for floating labels (#3939) (#3950)
|
||||||
|
* Add missing token validation on application settings page (#3976) #3978
|
||||||
|
* Webhook and hook_task clean up (#4006)
|
||||||
|
* Fix webhook bug of response info is not displayed in UI (#4023)
|
||||||
|
* Fix writer cannot read bare repo guide (#4033) (#4039)
|
||||||
|
* Don't force due date to current time (#3830) (#4057)
|
||||||
|
* Fix wiki redirects (#3919) (#4065)
|
||||||
|
* Fix attachment ENABLED (#4064) (#4066)
|
||||||
|
* Added deletion of an empty line at the end of file (#4054) (#4074)
|
||||||
|
* Use ResolveReference instead of path.Join (#4073)
|
||||||
|
* Fix #4081 Check for leading / in base before removing it (#4083)
|
||||||
|
* Respository's home page not updated after first push (#4075)
|
||||||
|
|
||||||
|
[1.5.2-1]
|
||||||
|
* Rebuild Gitea package because of https://github.com/go-gitea/gitea/issues/4167
|
||||||
|
* Adjust z-index for floating labels (#3939) (#3950)
|
||||||
|
* Add missing token validation on application settings page (#3976) #3978
|
||||||
|
* Webhook and hook_task clean up (#4006)
|
||||||
|
* Fix webhook bug of response info is not displayed in UI (#4023)
|
||||||
|
* Fix writer cannot read bare repo guide (#4033) (#4039)
|
||||||
|
* Don't force due date to current time (#3830) (#4057)
|
||||||
|
* Fix wiki redirects (#3919) (#4065)
|
||||||
|
* Fix attachment ENABLED (#4064) (#4066)
|
||||||
|
* Added deletion of an empty line at the end of file (#4054) (#4074)
|
||||||
|
* Use ResolveReference instead of path.Join (#4073)
|
||||||
|
* Fix #4081 Check for leading / in base before removing it (#4083)
|
||||||
|
* Respository's home page not updated after first push (#4075)
|
||||||
|
|
||||||
|
[1.5.3]
|
||||||
|
* Update Gitea to 1.4.3
|
||||||
|
* SECURITY
|
||||||
|
* HTML-escape plain-text READMEs (#4192) (#4214)
|
||||||
|
* Fix open redirect vulnerability on login screen (#4312) (#4312)
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix broken monitoring page when running processes are shown (#4203) (#4208)
|
||||||
|
* Fix delete comment bug (#4216) (#4228)
|
||||||
|
* Delete reactions added to issues and comments when deleting repository (#4232) (#4237)
|
||||||
|
* Fix wiki URL encoding bug (#4091) (#4254)
|
||||||
|
* Fix code tab link when viewing tags (#3908) (#4263)
|
||||||
|
* Fix webhook type conflation (#4285) (#4285)
|
||||||
|
|
||||||
|
[1.5.4]
|
||||||
|
* Allow customization using gitea's custom data directory
|
||||||
|
|
||||||
|
[1.6.0]
|
||||||
|
* Update Gitea to 1.5.0
|
||||||
|
* Security
|
||||||
|
* Check that repositories can only be migrated to own user or organizations (#4366) (#4370)
|
||||||
|
* Limit uploaded avatar image-size to 4096px x 3072px by default (#4353)
|
||||||
|
* Do not allow to reuse TOTP passcode (#3878)
|
||||||
|
* Features
|
||||||
|
* Add cli commands to regen hooks & keys (#3979)
|
||||||
|
* Add support for FIDO U2F (#3971)
|
||||||
|
* Added user language setting (#3875)
|
||||||
|
* Add topic support (#3711)
|
||||||
|
* Multiple assignees (#3705)
|
||||||
|
* Add protected branch whitelists for merging (#3689)
|
||||||
|
* Global code search support (#3664)
|
||||||
|
* Add label descriptions (#3662)
|
||||||
|
* Add issue search via API (#3612)
|
||||||
|
* Add repository setting to enable/disable health checks (#3607)
|
||||||
|
* Emoji Autocomplete (#3433)
|
||||||
|
* Implements generator cli for secrets (#3531)
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"author": "Gitea developers",
|
"author": "Gitea developers",
|
||||||
"description": "file://DESCRIPTION.md",
|
"description": "file://DESCRIPTION.md",
|
||||||
"tagline": "A painless self-hosted Git Service",
|
"tagline": "A painless self-hosted Git Service",
|
||||||
"version": "1.3.0",
|
"version": "1.6.0",
|
||||||
"healthCheckPath": "/healthcheck",
|
"healthCheckPath": "/healthcheck",
|
||||||
"httpPort": 3000,
|
"httpPort": 3000,
|
||||||
"addons": {
|
"addons": {
|
||||||
@@ -34,6 +34,6 @@
|
|||||||
"tags": [ "version control", "git", "code hosting", "development" ],
|
"tags": [ "version control", "git", "code hosting", "development" ],
|
||||||
"changelog": "file://CHANGELOG",
|
"changelog": "file://CHANGELOG",
|
||||||
"postInstallMessage": "file://POSTINSTALL.md",
|
"postInstallMessage": "file://POSTINSTALL.md",
|
||||||
"minBoxVersion": "1.8.1",
|
"minBoxVersion": "1.10.0",
|
||||||
"documentationUrl": "https://cloudron.io/documentation/apps/gitea/"
|
"documentationUrl": "https://cloudron.io/documentation/apps/gitea/"
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
This app packages Gitea <upstream>1.3.1</upstream>
|
This app packages Gitea <upstream>1.5.0</upstream>
|
||||||
|
|
||||||
Gitea is a painless self-hosted Git service. It is similar to GitHub, Bitbucket or Gitlab.
|
Gitea is a painless self-hosted Git service. It is similar to GitHub, Bitbucket or Gitlab.
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
FROM cloudron/base:0.10.0
|
FROM cloudron/base:0.10.0
|
||||||
|
|
||||||
ENV VERSION 1.3.1
|
ENV VERSION 1.5.0
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y openssh-server git && \
|
apt-get install -y openssh-server git && \
|
||||||
|
5
start.sh
5
start.sh
@@ -87,7 +87,7 @@ crudini --set "/run/gitea/app.ini" server SSH_PORT "${SSH_PORT}"
|
|||||||
crudini --set "/run/gitea/app.ini" server APP_DATA_PATH "/app/data/appdata"
|
crudini --set "/run/gitea/app.ini" server APP_DATA_PATH "/app/data/appdata"
|
||||||
crudini --set "/run/gitea/app.ini" repository ROOT "/app/data/repository"
|
crudini --set "/run/gitea/app.ini" repository ROOT "/app/data/repository"
|
||||||
crudini --set "/run/gitea/app.ini" repository.upload TEMP_PATH "/run/gitea/tmp/uploads"
|
crudini --set "/run/gitea/app.ini" repository.upload TEMP_PATH "/run/gitea/tmp/uploads"
|
||||||
crudini --set "/run/gitea/app.ini" mailer HOST "${MAIL_SMTP_SERVER}:${MAIL_SMTP_PORT}"
|
crudini --set "/run/gitea/app.ini" mailer HOST "${MAIL_SMTP_SERVER}:${MAIL_SMTPS_PORT}"
|
||||||
crudini --set "/run/gitea/app.ini" mailer USER "${MAIL_SMTP_USERNAME}"
|
crudini --set "/run/gitea/app.ini" mailer USER "${MAIL_SMTP_USERNAME}"
|
||||||
crudini --set "/run/gitea/app.ini" mailer PASSWD "${MAIL_SMTP_PASSWORD}"
|
crudini --set "/run/gitea/app.ini" mailer PASSWD "${MAIL_SMTP_PASSWORD}"
|
||||||
crudini --set "/run/gitea/app.ini" mailer FROM "${MAIL_FROM}"
|
crudini --set "/run/gitea/app.ini" mailer FROM "${MAIL_FROM}"
|
||||||
@@ -97,8 +97,7 @@ crudini --set "/run/gitea/app.ini" log MODE "console"
|
|||||||
crudini --set "/run/gitea/app.ini" log ROOT_PATH "/run/gitea"
|
crudini --set "/run/gitea/app.ini" log ROOT_PATH "/run/gitea"
|
||||||
crudini --set "/run/gitea/app.ini" indexer ISSUE_INDEXER_PATH "/app/data/appdata/indexers/issues.bleve"
|
crudini --set "/run/gitea/app.ini" indexer ISSUE_INDEXER_PATH "/app/data/appdata/indexers/issues.bleve"
|
||||||
|
|
||||||
|
mkdir -p /app/data/repository /app/data/ssh /app/data/custom
|
||||||
mkdir -p /app/data/repository /app/data/ssh
|
|
||||||
|
|
||||||
chown -R git:git /app/data /run/gitea
|
chown -R git:git /app/data /run/gitea
|
||||||
|
|
||||||
|
@@ -9,4 +9,4 @@ stdout_logfile=/dev/stdout
|
|||||||
stdout_logfile_maxbytes=0
|
stdout_logfile_maxbytes=0
|
||||||
stderr_logfile=/dev/stderr
|
stderr_logfile=/dev/stderr
|
||||||
stderr_logfile_maxbytes=0
|
stderr_logfile_maxbytes=0
|
||||||
environment=HOME="/home/git",USER="git"
|
environment=HOME="/home/git",USER="git",GITEA_CUSTOM="/app/data/custom"
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"superagent": "^1.4.0"
|
"superagent": "^1.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"chromedriver": "^2.38.2",
|
||||||
"selenium-server-standalone-jar": "^3.3.1",
|
"selenium-server-standalone-jar": "^3.3.1",
|
||||||
"selenium-webdriver": "^3.3.0",
|
"selenium-webdriver": "^3.3.0",
|
||||||
"superagent": "^1.8.5"
|
"superagent": "^1.8.5"
|
||||||
|
74
test/test.js
74
test/test.js
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
require('chromedriver');
|
||||||
|
|
||||||
var execSync = require('child_process').execSync,
|
var execSync = require('child_process').execSync,
|
||||||
ejs = require('ejs'),
|
ejs = require('ejs'),
|
||||||
expect = require('expect.js'),
|
expect = require('expect.js'),
|
||||||
@@ -71,7 +73,7 @@ describe('Application life cycle test', function () {
|
|||||||
expect(app).to.be.an('object');
|
expect(app).to.be.an('object');
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAvatar(done) {
|
function setAvatarOld(done) {
|
||||||
browser.get('https://' + app.fqdn + '/user/settings/avatar').then(function () {
|
browser.get('https://' + app.fqdn + '/user/settings/avatar').then(function () {
|
||||||
return browser.findElement(by.xpath('//input[@type="file" and @name="avatar"]')).sendKeys(path.resolve(__dirname, '../logo.png'));
|
return browser.findElement(by.xpath('//input[@type="file" and @name="avatar"]')).sendKeys(path.resolve(__dirname, '../logo.png'));
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
@@ -87,6 +89,25 @@ describe('Application life cycle test', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAvatar(done) {
|
||||||
|
if (app.manifest.version === '1.5.4') return setAvatarOld(done);
|
||||||
|
|
||||||
|
browser.get('https://' + app.fqdn + '/user/settings').then(function () {
|
||||||
|
var button = browser.findElement(by.xpath('//label[contains(text(), "Use Custom Avatar")]'));
|
||||||
|
return browser.executeScript('arguments[0].scrollIntoView(false)', button);
|
||||||
|
}).then(function () {
|
||||||
|
return browser.findElement(by.xpath('//label[contains(text(), "Use Custom Avatar")]')).click();
|
||||||
|
}).then(function () {
|
||||||
|
return browser.findElement(by.xpath('//input[@type="file" and @name="avatar"]')).sendKeys(path.resolve(__dirname, '../logo.png'));
|
||||||
|
}).then(function () {
|
||||||
|
return browser.findElement(by.xpath('//button[contains(text(), "Update Avatar")]')).click();
|
||||||
|
}).then(function () {
|
||||||
|
return browser.wait(until.elementLocated(by.xpath('//p[contains(text(),"Your avatar has been updated.")]')), TIMEOUT);
|
||||||
|
}).then(function () {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function checkAvatar(done) {
|
function checkAvatar(done) {
|
||||||
return done();
|
return done();
|
||||||
superagent.get('https://' + app.fqdn + '/avatars/a3e6f3316fc1738e29d621e6a26e93d3').end(function (error, result) {
|
superagent.get('https://' + app.fqdn + '/avatars/a3e6f3316fc1738e29d621e6a26e93d3').end(function (error, result) {
|
||||||
@@ -127,12 +148,7 @@ return done();
|
|||||||
function addPublicKey(done) {
|
function addPublicKey(done) {
|
||||||
var publicKey = fs.readFileSync(__dirname + '/id_rsa.pub', 'utf8');
|
var publicKey = fs.readFileSync(__dirname + '/id_rsa.pub', 'utf8');
|
||||||
|
|
||||||
var sshPage;
|
const sshPage = 'https://' + app.fqdn + '/user/settings/keys';
|
||||||
if (app.manifest.version === '1.0.3') {
|
|
||||||
sshPage = 'https://' + app.fqdn + '/user/settings/ssh';
|
|
||||||
} else {
|
|
||||||
sshPage = 'https://' + app.fqdn + '/user/settings/keys';
|
|
||||||
}
|
|
||||||
|
|
||||||
browser.get(sshPage).then(function () {
|
browser.get(sshPage).then(function () {
|
||||||
return browser.findElement(by.xpath('//div[text()="Add Key"]')).click();
|
return browser.findElement(by.xpath('//div[text()="Add Key"]')).click();
|
||||||
@@ -216,10 +232,42 @@ return done();
|
|||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addCustomFile(done) {
|
||||||
|
fs.writeFileSync('/tmp/customfile.txt', 'GOGS TEST', 'utf8');
|
||||||
|
execSync('cloudron exec -- mkdir -p /app/data/custom/public');
|
||||||
|
execSync('cloudron push /tmp/customfile.txt /app/data/custom/public/customfile.txt');
|
||||||
|
fs.unlinkSync('/tmp/customfile.txt');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkCustomFile(done) {
|
||||||
|
superagent.get('https://' + app.fqdn + '/customfile.txt').end(function (error, result) {
|
||||||
|
if (error) return done(error);
|
||||||
|
|
||||||
|
expect(result.text).to.contain('GOGS TEST');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function fileExists() {
|
function fileExists() {
|
||||||
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendMail(done) {
|
||||||
|
browser.get('https://' + app.fqdn + '/admin/config').then(function () {
|
||||||
|
var button = browser.findElement(by.xpath('//button[@id="test-mail-btn"]'));
|
||||||
|
return browser.executeScript('arguments[0].scrollIntoView(true)', button);
|
||||||
|
}).then(function () {
|
||||||
|
return browser.findElement(by.xpath('//input[@name="email"]')).sendKeys('test@cloudron.io');
|
||||||
|
}).then(function () {
|
||||||
|
return browser.findElement(by.xpath('//button[@id="test-mail-btn"]')).click();
|
||||||
|
}).then(function () {
|
||||||
|
return browser.wait(until.elementLocated(by.xpath('//p[contains(text(),"A testing email has been sent to \'test@cloudron.io\'")]')), TIMEOUT);
|
||||||
|
}).then(function () {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
xit('build app', function () {
|
xit('build app', function () {
|
||||||
execSync('cloudron build', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
execSync('cloudron build', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||||
});
|
});
|
||||||
@@ -234,7 +282,7 @@ return done();
|
|||||||
if (error) return done(error);
|
if (error) return done(error);
|
||||||
if (result.statusCode !== 200) return done(new Error('Login failed with status ' + result.statusCode));
|
if (result.statusCode !== 200) return done(new Error('Login failed with status ' + result.statusCode));
|
||||||
|
|
||||||
token = result.body.token;
|
token = result.body.accessToken;
|
||||||
|
|
||||||
superagent.get('https://' + inspect.apiEndpoint + '/api/v1/profile')
|
superagent.get('https://' + inspect.apiEndpoint + '/api/v1/profile')
|
||||||
.query({ access_token: token }).end(function (error, result) {
|
.query({ access_token: token }).end(function (error, result) {
|
||||||
@@ -262,6 +310,7 @@ return done();
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can login', login);
|
it('can login', login);
|
||||||
|
it('can send mail', sendMail);
|
||||||
it('can set avatar', setAvatar);
|
it('can set avatar', setAvatar);
|
||||||
it('can get avatar', checkAvatar);
|
it('can get avatar', checkAvatar);
|
||||||
|
|
||||||
@@ -276,8 +325,11 @@ return done();
|
|||||||
it('can add and push a file', pushFile);
|
it('can add and push a file', pushFile);
|
||||||
it('can edit file', editFile);
|
it('can edit file', editFile);
|
||||||
|
|
||||||
|
it('can add custom file', addCustomFile);
|
||||||
|
it('can check custom file', checkCustomFile);
|
||||||
|
|
||||||
it('can restart app', function (done) {
|
it('can restart app', function (done) {
|
||||||
execSync('cloudron restart --wait');
|
execSync('cloudron restart --wait --app ' + app.id);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -301,7 +353,7 @@ return done();
|
|||||||
|
|
||||||
it('move to different location', function () {
|
it('move to different location', function () {
|
||||||
//browser.manage().deleteAllCookies(); // commented because of error "'Network.deleteCookie' wasn't found"
|
//browser.manage().deleteAllCookies(); // commented because of error "'Network.deleteCookie' wasn't found"
|
||||||
execSync('cloudron configure --wait --location ' + LOCATION + '2', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
execSync('cloudron configure --wait --location ' + LOCATION + '2 --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
var inspect = JSON.parse(execSync('cloudron inspect'));
|
||||||
app = inspect.apps.filter(function (a) { return a.location === LOCATION + '2'; })[0];
|
app = inspect.apps.filter(function (a) { return a.location === LOCATION + '2'; })[0];
|
||||||
expect(app).to.be.an('object');
|
expect(app).to.be.an('object');
|
||||||
@@ -350,6 +402,8 @@ return done();
|
|||||||
execSync('cloudron install --wait --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
execSync('cloudron install --wait --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can login', login);
|
||||||
|
it('can send mail', sendMail);
|
||||||
it('can get avatar', checkAvatar);
|
it('can get avatar', checkAvatar);
|
||||||
it('can clone the url', cloneRepo);
|
it('can clone the url', cloneRepo);
|
||||||
it('file exists in cloned repo', fileExists);
|
it('file exists in cloned repo', fileExists);
|
||||||
|
Reference in New Issue
Block a user