Set GitHub default branch through API call - api

I need to create a branch dev which is other than master branch. Also need to set dev as default branch using GITHUB API.
Please share details if anyone know which API to call or a way to do it, programmatically. I know that it can be done through the Web UI, however I am looking for a solution that does not involve manual intervention.

I don't have enough reputation to reply to the Adam's comment above but the problem is name is a required field. The JSON should actually be:
PATCH /repos/:owner/:repo
{
"name":":repo"
"default_branch": "dev"
}

Following the guide here: https://developer.github.com/v3/repos/#edit , default_branch input should make what you want
default_branch (string): Updates the default branch for this repository.
So, you should submit a PATCH request like:
PATCH /repos/:owner/:repo
{"default_branch": "dev"}

You can use requests library:
import requests
access_token = "your_access_token"
headers = {'Authorization': f'token {access_token}',
'Content-Type':'application/json'}
data={"name":"knowledge-engine", "default_branch": "development"}
owner = "username"
repo_name = "repo_name"
url = f"https://api.github.com/repos/{owner}/{repo_name}"
requests.patch(url, data=json.dumps(data), headers=headers)
<Response [200]>
Docs:
https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line
http://docs.python-requests.org/en/master/
https://developer.github.com/v3/repos/#edit

Easiest way to update the default branch if you have the github cli:
gh api repos/{owner}/{repo} --method PATCH --field 'default_branch=dev'
Note the CLI will replace the {owner} and {repo} for you if you are in the locally checked out repository.

Related

How do I get sorted results from the Google Photos search API?

I'm using the search API for Google Photos documented here. I'd like the results in the response to be sorted from newest to oldest, but by default, the results are sorted from oldest to newest. Is there a way to reverse the sorting?
I believe your goal as follows.
You want to sort the result values from the method of "Method: mediaItems.search".
You want to sort the values from oldest to newest.
Issue and workaround:
Unfortunately, in the current stage, it seems that there is no parameter for sorting the returned values for the the method of "Method: mediaItems.search" in Google Photos API. Also, it seems that such parameter is not existing in the method of "mediaItems.list".
By the way, it was found that when albumId is used in the request body for the method of "Method: mediaItems.search", the returned values are sorted as the ascending order. If you use the albumn ID, I think that your goal can be achieve by this.
On the other hand, when albumId is NOT used in the request body, the returned values are sorted as the descending order. And also, it seems that when filteres is used in the request body, the returned values are sorted as the descending order.
From your question, I thought that in your situation, albumId might be not used. So in this case, as the current workaround, how about sorting the values using a script after the values are retrieved? In this answer, I would like to propose to use the Web Apps created by Google Apps Script as a wrapper API.
Usage:
1. Create new project of Google Apps Script.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
2. Linking Cloud Platform Project to Google Apps Script Project.
About this, you can see the detail flow at here.
And also, please enable Google Photos API at API console.
3. Add scope.
In this case, please addt the scope of https://www.googleapis.com/auth/photoslibrary to the manifest file (appsscript.json).
4. Script.
Please copy and paste the following script (Google Apps Script) to the script editor. This script is for the Web Apps. This Web Apps is used as an API.
function doGet(e) {
const key = "sampleKey"; // This is used for using this Web Apps.
try {
if (e.parameter.key != key) throw new Error("Invalid key.");
const albumId = e.parameter.albumId;
const filters = e.parameter.filters;
const sort = e.parameter.sort;
const headers = {"Authorization": "Bearer " + ScriptApp.getOAuthToken()};
const url = "https://photoslibrary.googleapis.com/v1/mediaItems:search";
let mediaItems = [];
let pageToken = "";
const metadata = {pageSize: 100, pageToken: pageToken};
if (albumId) metadata.albumId = albumId;
if (filters) metadata.filters = JSON.parse(filters);
do {
const params = {
method: "post",
headers: headers,
contentType: "application/json",
payload: JSON.stringify(metadata),
}
const res = UrlFetchApp.fetch(url, params);
const obj = JSON.parse(res.getContentText());
mediaItems = mediaItems.concat(obj.mediaItems);
pageToken = obj.nextPageToken || "";
} while (pageToken);
if (mediaItems.length > 0) {
if (sort && sort == "ascending") {
mediaItems.sort((a, b) => new Date(a.mediaMetadata.creationTime) < new Date(b.mediaMetadata.creationTime) ? -1 : 1);
}
return ContentService.createTextOutput(JSON.stringify({values: mediaItems}));
}
return ContentService.createTextOutput(JSON.stringify({error: "No values."}));
} catch(err) {
return ContentService.createTextOutput(JSON.stringify({error: err.message}));
}
}
5. Deploy Web Apps.
The detail information can be seen at the official document.
On the script editor, at the top right of the script editor, please click "click Deploy" -> "New deployment".
Please click "Select type" -> "Web App".
Please input the information about the Web App in the fields under "Deployment configuration".
Please select "Me" for "Execute as".
This is the important of this workaround.
Please select "Anyone" for "Who has access".
In this case, the user is not required to use the access token. So please use this as a test case.
When you want to use the access token, please set it to Anyone with Google account or Only myself. By this, the user can access to the Web Apps using the access token. When you use the access token, please include the scope of https://www.googleapis.com/auth/drive.readonly or https://www.googleapis.com/auth/drive.
Please click "Deploy" button.
When "The Web App requires you to authorize access to your data" is shown, please click "Authorize access".
Automatically open a dialog box of "Authorization required".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Copy the URL of Web App. It's like https://script.google.com/macros/s/###/exec.
When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
6. Testing.
As the test of this Web Apps, I would like to propose to use the following curl command. Please replace https://script.google.com/macros/s/###/exec with your Web Apps URL.
Simple use:
In this curl command, the result value is returned as the ascending order of oldest to newest.
$ curl -GL -d "key=sampleKey" -d "sort=ascending" https://script.google.com/macros/s/###/exec
Use albumId:
When you want to use the album ID, please use the following curl command.
$ curl -GL -d "albumId=###" -d "key=sampleKey" -d "sort=ascending" https://script.google.com/macros/s/###/exec
In this case, even when -d "sort=ascending" is not used, the result value is returned as the ascending order of oldest to newest.
Use filters:
When you want to use the filters, please use the following curl command.
$ curl -GL -d 'filters={"dateFilter":{"ranges":[{"startDate":{"year":2020},"endDate":{"year":2021}}]}}' -d "key=sampleKey" -d "sort=ascending" https://script.google.com/macros/s/###/exec
In this command, the values of 2020 - 2021 are returned as the ascending order of oldest to newest.
Note:
Although when I searched this at the Google issue tracker, I couldn't find about it. So how about reporting this as the future request? Ref
References:
Method: mediaItems.search
Related thread.
How to use Google Photos API Method: mediaItems.search in Google apps script for a spreadsheet
Google photos api adding photos not working, upload seems to work
Google Apps Scripts: import (upload) media from Google Drive to Google Photos?

Can I get the most recent commit of a repository with Bitbucket API?

I am using Bitbucket API to retrieve different information. However I am looking to do a request that retrieves the latest commit for a repository. I initially thought it would be done like this:
https://bitbucket.org/!api/2.0/repositories/xxxx/xxxx/commits?limit=1
This just showed all the commits as normal but I want to show the most recent one. From looking through the API documentation I can't find anything that shows about limiting the number of commits to show. So was wondering if anyone could point me in the right direction?
Okay this wasn't straight forward either and I spent a couple of hours looking for how to do this myself. It ended up being easy if not unfortunate. Simply put the available API will not return just a target commit (like the latest). You have do parse it yourself. The following api:
"https://api.bitbucket.org/2.0/repositories/<project>/<repo>/commits/<branch>?limit=1"
Will still return ALL the commits for that particular branch BUT in order. So you can simply just grab the first result on the first page that is returned and that's the most recent commit for that branch. Here is a basic python example:
import os
import requests
import json
headers = {"Content-Type": "application/json"}
USER = ""
PASS = ""
def get_bitbucket_credentials():
global USER, PASS
USER = "<user>"
PASS = "<pass>"
def get_commits(project, repo, branch):
return json.loads(call_url("https://api.bitbucket.org/2.0/repositories/%s/%s/commits/%s?limit=1" % (project, repo, branch)))
def get_modified_files(url):
data = json.loads(call_url(url))
file_paths = []
for value in data["values"]:
file_paths.append(value["new"]["path"])
return file_paths
def call_url(url):
global USER, PASS
response = requests.get(url, auth=(USER, PASS), headers=headers)
if response.status_code == requests.codes.ok:
return response.text
return ""
if __name__ == "__main__":
get_bitbucket_credentials()
data = get_commits("<project>","<repo>","<branch>")
for item in data["values"]:
print("Author Of Commit: "+item["author"]["raw"])
print("Commit Message: "+item["rendered"]["message"]["raw"])
print("List of Files Changed:")
print(get_modified_files(item["links"]["diff"]["href"].replace("/diff/","/diffstat/")))
break
You can run the above example:
python3 mysavedfile.py
and that will output like:
Author Of Commit: Persons Name <personemail#email.com>
Commit Message: my commit message
List of Files Changed:
['file1.yaml','file2.yaml']
There a simple way to do it, using Bitbucket pagination mechanism.
Like so:
https://bitbucket.org/!api/2.0/repositories/xxxx/xxxx/commits?pagelen=1
Normally you'll need to specify the page number, "page=1", but the default is 1 so...

When I import Swagger API to Postman, all request names end up blank in Postman GUI

I am QA engineer. The Dev team produces documentation for our product's RESTful API using Swagger. I need to import this to Postman to make it easy to invoke the product's API.
After importing the JSON file (in Swagger format) into Postman, there is 1 but big problem: All titles (and descriptions) of individual requests are blank! (see screen shot below).
Apparently, this is a known issue, documented here: https://github.com/postmanlabs/postman-app-support/issues/1434
We have literally hundreds of requests. I need to find a sufficiently effective yet simple way to ensure all request titles in Postman are populated with a value which I would like to calculate on the fly.
I have been considering the following approach:
Write a command line tool (using NodeJS or another
solid platform) which will receive:
1. ID of the collection to fix
2. api key
It will iterate through all requests in the
collection. For each request: if Name field is
blank, then a substring of the request URL
will be assigned to the Name field; if name is
not blank, the request is left alone.
What I am unsure about:
Can I do this programmatically from Postman? It does not make sense to put this code into any one individual request (as pre or post).
(If I have to code this util outside of Postman)
For NodeJS there are "postman-collection" and
"postman-sdk" but I am slightly confused which I
should use.
Unfortunately, I have not yet found any suitable > library for maintaining Postman collections using C# > or Java.
I am quite frankly confused by the available options. Any guidance will be appreciated.
I had the same problem, solved it thanks to Ian T Price solution (just copy operationId value into a new key summary). I decided to write a little javascript utility for this:
function swagPostman(swaggerJson) {
for (let path in swaggerJson.paths) {
let methods = ["get", "head", "post", "put", "delete", "connect", "options", "trace", "patch"];
methods.map(method => {
if ((swaggerJson.paths[path] || {})[method]) {
swaggerJson.paths[path][method].summary =
swaggerJson.paths[path][method].operationId;
}
});
}
return JSON.stringify(swaggerJson);
}
Also made a simple pen where to run the script with a GUI: https://codepen.io/0x616c65/full/pMaQpb. You just copy-paste your swagger.json file in that pen and woilĂ !
A simple answer to this is to add a line summary: <RequestName>
I came across this problem using the excellent APIs-Gurus OpenAPIDirectory repo
These swagger.yaml files have a operationId: line which can be duplicated and the key replaced with summary: using:
awk '{if (!/ operationId:/) {print ; next} ; { print; a=gensub(/ operationId:/, " summary:",1) ; print a}}' swagger.yaml > swagger-new.yaml
Importing this into Postman then shows the correct request name.
PostMan is separating out the Import/Export functions in to separate plug-ins but their plug-in model leaves a lot to be desired at the current time.

Alamofire V3 how to invalidate credential

I'm using Alamofire V3 with iOS 9 and I'm doing a simple request as in the README
Alamofire.request(.GET, WS_URL)
.authenticate(user: user, password: password)
.validate(statusCode: 200..<300)
.responseJSON { response in
...
}
After a first valid request, I changed the credential with invalid ones and the request succeed, but it should fail.
How can I invalidate previous credentials?
UPDATE
I've found a possible solution but I'm not sure that it 's the best one.
let plainString = "\(user):\(password)
let plainData = plainString.dataUsingEncoding(NSUTF8StringEncoding)
let base64String = plainData?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
let headers = ["Authorization": "Basic " + base64String!]
Alamofire.request(.GET, urlRequest, headers: headers)
.authenticate(usingCredential: self.credential)
.responseJSON{ responseJson in
...
}
Thanks
As written in the documentation
Depending upon your server implementation, an Authorization header may also be appropriate
Assuming your endpoint is ok and they you are getting success responses...
let defines a constant which cannot be modified once set.
var defines a variable which can.
Try using a variable instead, if you've assign it compile then re-compile. Otherwise using a different name for your variable.
print them to see their values.
In these cases, the "reset" command is your best friend:
$ git reset --soft HEAD~1
Reset will rewind your current HEAD branch to the specified revision.
Note the --soft flag: this makes sure that the changes in undone revisions are preserved. After running the command, you'll find the changes as uncommitted local modifications in your working copy.
If you don't want to keep these changes, simply use the --hard flag. Be sure to only do this when you're sure you don't need these changes anymore.
$ git reset --hard HEAD~1

send delete request to controller in cucumber step definition

Does any of you know how to do (implement) something like this:
sample.feature
...
scenario: unauthorized user cannot delete event
Given list of events
When event is deleted
Then nothing happen
...
sample_steps.rb
...
When /^event is deleted$/ do
delete (_path_to_controller_ + "/%d" % #events.first().id)
...
Of course in this step I want to send a request according to the result of rake routes, which is something like this (I've moved resources under admin path):
rake routes
...
DELETE /admin/controller_name/:id(.:format) controller_name#destroy
...
I have been experimenting and searching internet for so long and yet I don't know how to do it :(
I've used Rack::Test in the past to send DELETE requests to an API:
When /^event is deleted$/ do
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
authorize "username", "password"
url = _path_to_controller_ + "/%d" % #events.first().id)
delete url
end
Having said that, I'm not sure I'd recommend it in your case. Is the event going to be deleted from some action in the interface such as clicking a button? If so, you should use capybara to log in and click the button. This gives you the benefit of full integration coverage and you don't have to deal with Rack::Test (not that it's a bad tool, but it's another tool).
Uff I've solved the problem.
Great Thanks to Beerlington
So in this post I will sum up my time with the problem and its solution.
Related topics and documentation
StackOverflow: HTTP basic auth for Capybara
Devise: How To: Use HTTP Basic Authentication
Background
I'm using devise gem for authentication. My goal was to check if possible is manual hacking to resource management features like delete.
Problem
Above ;D
Solution
When /^event is deleted$/ do
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
authorize "username", "password"
url = _path_to_controller_ + "/%d" % #events.first().id)
delete url
end
is not working with default devise configuration. Because it uses HTTP authentication which is disabled by default.
config/initializers/devise.rb
# Tell if authentication through HTTP Basic Auth is enabled. False by default.
# It can be set to an array that will enable http authentication only for the
# given strategies, for example, `config.http_authenticatable = [:token]` will
# enable it only for token authentication.
# config.http_authenticatable = false
So if we want to make above test working, we need to change last line to:
config.http_authenticatable = true
But the question is do we really wanna do it ?
And as a last note: header calls are optional. Records are deleted with or without them.
with them delete return with status code : 204 No Content
and without them delete return with status code : 302 Found