Push version Number to git/azure devops automatically - azure-devops

I have these three commands in my package.json
{
"build-major": "npm version major --no-git-tag-version && node ./replace.build.js && node --max_old_space_size=8192 node_modules/#angular/cli/bin/ng build --prod --base-href /QMobile/",
"build-minor": "npm version minor --no-git-tag-version && node ./replace.build.js && node --max_old_space_size=8192 node_modules/#angular/cli/bin/ng build --prod --base-href /QMobile/",
"build-patch": "npm version patch --no-git-tag-version && node ./replace.build.js && node --max_old_space_size=8192 node_modules/#angular/cli/bin/ng build --prod --base-href /QMobile/",
}
My replace.build.js Contains following Code:
var replace = require('replace-in-file');
var package = require("./package.json");
var buildVersion = package.version;
const options = {
files: 'src/environments/environment.prod.ts',
from: /version: '(.*)'/g,
to: "version: '"+ buildVersion + "'",
allowEmptyPaths: false,
};
const htmlOptions={
files:'src/index.html',
from: /<meta name="version" content="(.*)">/g,
to: '<meta name="version" content="'+buildVersion+'">',
allowEmptyPaths: false
}
try {
let changedFiles = replace.sync(options);
if (changedFiles == 0) {
throw "Please make sure that file '" + options.files + "' has \"version: ''\"";
}
let indexFileChanged = replace.sync(htmlOptions);
if (indexFileChanged == 0) {
throw "Index.html Version Change Failed";
}
console.log('Build version set: ' + buildVersion);
}
catch (error) {
console.error('Error occurred:', error);
throw error
}
So every time i take my Angular Build, i get 3 files changes?
index.html, environment.prod.ts and package.json
I am looking at a solution to make these changes get pushed to the current branch too while build is in Process or a Standard way to maintain the Build Number in sync with all Branches.

I am looking at a solution to make these changes get pushed to the
current branch too while build is in Process or a Standard way to
maintain the Build Number in sync with all Branches.
Just put a git-related task at the end of your pipeline to push the changed files to remote branch. You can use CMD task, Powershell task or third-party git tasks here to push the changed files.
For my pipeline that calls Replace token task to modify one file:
1.The cmd task at the start of the pipeline:
git checkout $(Build.SourceBranchName)
git config --global user.email "xxx#xxx.com"
git config --global user.name "xxx"
For build source directory, git repo is in HEAD detached by default, so we need to switch to the build branch by git checkout first.
2.The cmd task at the end of the pipeline:
git add .
git commit -m "Update files in Build $(Build.BuildNumber)."
git push https://{MyPat}#dev.azure.com/{OrganizationName}/{ProjectName}/_git/{RepoName} $(Build.SourceBranchName)
Check this similar issue for more details about git push command. About PAT see here. You can also define the PAT as an secret variable and reference it in command.
You can put your real tasks between the first CMD and the last CMD, then every time when the pipeline is finished, the changes will be pushed to current branch. (With BuildNumber in commit message.)

Related

Fail a merge or build if a particular file has changed?

On VSTS, we have some files we want to protect on certain branches. How can one fail a merge/build if a particular file has changed?
First prize is to configure this on the build server, which in this case is VisualStudio.com (VSTS / GIT).
Scenario: we have various release branches v1, v2, v3. We want to protect the packages.json file to prevent anyone updating Nuget packages on these branches. So if the package.json file has changed on a pull request into "v3", don't allow the merge.
For Git, you can protect a certain branch (not a certain file), then all the files exist in the branch will be protected.
You can use Branch security which users/groups can contribute for the branch.
Or you can use Branch Policies to protect not commit changes on the branch directly but use pull request to make changes etc.
Or you can lock a branch to prevent updating.
To expanded Starain's answer:
First create a build definition for the branch you want to protected (such as select V3 branch in get sources step). And add a powershell task with the content below:
$head=$(git rev-parse HEAD)
$parents=$(git rev-list --parents -n 1 $head)
$p1,$p2,$p3=$parents.split(' ')
If ($p1 = $head)
{
$parent1=$p2
$parent2=$p3
}
ElseIf ($p2 = $head)
{
$parent1=$p1
$parent2=$p3
}
Else
{
$parent1=$p1
$parent2=$p2
}
$outp1=$(git diff $head $parent1 --name-only)
$outp2=$(git diff $head $parent2 --name-only)
If ($outp1 -contains 'package.json')
{
echo "changed the specified file on the branch which contains commit $parent1"
exit 1
}
If ($outp2 -contains 'package.json')
{
echo "changed the specified file on the branch which contains commit $parent2"
exit 1
}
So that when the file package.json has been change, powershell script will fail the build result.
Then add the branch policy for the branch which you want to protect.
Add build policy -> select the build definition you just created -> Policy requirement as Required -> Build expiration 0.1 hours (6 min) or other values since it’s every fast to queue a build with a powershell task -> save.
You can try to do it in the build, simple workflow:
Configure branch policy for a succeed build required
Check whether the specific file changed in that build
Fail build if specific file has been changed
You can put a required reviewer for a particular folder/file in VSTS for a particular branch.
In this way the person won't be able to check-in without getting an approval from the required reviewer.
Git doesn't really work that way; individual files don't have any sort of security on them.
You could use a pre-commit hook, but it's important to note that those hooks are client-side, not server-side -- each user would have to set up a pre-commit hook.
VSTS/TFS doesn't support Git server hooks (at least, not to the extent that it can block a push), otherwise a pre-receive or update hook would be exactly what you want.

Powershell script in VSTS Build Definition not updating AssemblyVersion.cs

I have a Project hosted in VSTS and I'm experimenting with the Build Definitions. I'm trying to execute a powershell script that updates the AssemblyVersion.cs before the Project is built. When I run the script locally it works fine, but when it's ran during the Build process, the script runs without error, but the AssemblyVersion.cs is not updated.
$regex = '\[assembly: AssemblyVersion\("(.*)"\)\]'
$assemblyInfoPath = "..\Properties\AssemblyInfo.cs"
(Get-Content $assemblyInfoPath) | ForEach-Object {
if($_ -match $regex)
{
# Get current version, and update revision number
$version = [version]$matches[1]
$newVersion = "{0}.{1}.{2}.{3}" -f $version.Major, $version.Minor, $version.Build, ($version.Revision + 1)
'[assembly: AssemblyVersion("{0}")]' -f $newVersion
Write-Host "Version updated to: $newVersion"
}
else
{
$_
}
} | Set-Content $assemblyInfoPath
The Build output states that the version has been updated, but when I view AssemblyInfo.cs in the File Viewer it shows the old version.
The build process doesn't check in/commit changes made to source code automatically at the end of the process. You have to write a script to do that.
You need to checkin or push changes to remote repository.
If you are using TFVC, there is TFVC Build Tasks extension that includes TFVC-Check-in Changes step/task that can check in changes.
If you are using Git, you can add these steps/tasks to push changes:
Command Line (Tool: git; Arguments: add **\*.*; Working folder: $(build.sourcesdirectory))
Command Line (Tool: git; Arguments: commit -m "update"; Working folder: $(build.sourcesdirectory))
Command Line (Tool: git; Arguments: push origin HEAD:$(Build.SourceBranchName); Working folder: $(build.sourcesdirectory))
On the other hand, you also could build a custom build/release task and use it in your build/release. More information about custom build/release task, you can refer to: Add a build task
Note: It is not recommended to checkin/push changes to the remote repository in build or release.

Jenkins publish changes in repository to github using pipeline and groovy

I have a jenkins organization pipeline job that executes on all repositories that have "Jenkinsfile" defined. The job clones the repository from github, then runs the powershell script that increments the version number in the file. I'm now trying to publish that updated file back to the original repository on github, so when developer pulls the changes he gets the latest version number.
I tried using the script (inside "jenkinsfile") as suggested in jenkins JIRA (https://issues.jenkins-ci.org/browse/JENKINS-28335), but to no avail. Any suggestions will be appreciated. Basically need to execute "git commit" and "git push" using the same parameters defined for a job.
Just as a reference, here is a previous solution used for free style (not pipeline job): How to push changes to github after jenkins build completes?.
Actually found couple solutions, first I modied script from Jenkins like this (some objects changed in workflow pipeline):
import hudson.FilePath
import org.eclipse.jgit.transport.URIish
node {
env.WORKSPACE = pwd()
stage 'Checkout'
checkout scm
def build = manager.build
def listener = manager.listener
def workspace = new FilePath(new File(env.WORKSPACE))
def environment = build.getEnvironment(listener)
final def project = build.getParent()
final def gitScm = project.getTypicalSCM()
final def gitClient = gitScm.createClient(listener, environment, build, workspace);
final def gitTagName = "TAG_NAME"
final def comment = "COMMENT"
final def remoteURI = new URIish("origin")
gitClient.tag(gitTagName, comment)
gitClient.push().tags(true).to(remoteURI).execute()
}
You need to run the script multiple times and then allow code execution in jenkins (manage jenkins->in process script approval).
Another solution, much simpler (using this one for now):
bat "\"${tool 'Git'}\" config user.email \"ci#virtocommerce.com\""
bat "\"${tool 'Git'}\" config user.name \"Virto Jenkins\""
bat "\"${tool 'Git'}\" commit -am \"Updated version number\""
bat "\"${tool 'Git'}\" push origin HEAD:master -f"
You have to have Git tool with a name "Git" configured in Jenkins.

How to prevent travis jobs after each commit?

I am developing a library on github that has travis checks attached to it. I'd like to have a WIP pull request open to discuss ideas easily. There is a lot of tests set up for the project on travis, so I'd like to not trigger the tests every time I push a commit (to prevent server for being overloaded), as the code is not expected to pass anyway.
Is there a way I could do this on github without having access to travis configuration?
To skip builds on a per-commit basis you can add [ci skip] to the commit message, as described in the Docs, for example:
Before: Add blerb.
After:
Add blerb
[ci skip]
To skip all non-PR builds, you can early-exit if the TRAVIS_PULL_REQUEST environnment variable is set to "false" fron your .travis.yml:
before_install: # Earliest build step
- if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo "Not a PR, skipping" && exit; fi
My approach is to use an alias that I defined that appends the [ci skip] to each commit message of the current branch.
wip = "!f() { git filter-branch -f --msg-filter 'sed -e "\"s/$/ \\[ci skip\\]/g\""' ${1-master}..HEAD ; }; f"
unwip = "!f() { git filter-branch -f --msg-filter 'sed -e "\"s/ \\[ci skip\\]//g\""' ${1-master}..HEAD ; }; f"
wpush = "!f() { git wip $1 && git fpush && git unwip $1 ; }; f"
So basically what I do is simply git wpush.

How can I move a Git repository with all branches from Bitbucket to GitHub?

What is the best way to move a Git repository with all branches and full history from Bitbucket to GitHub?
Is there a script or a list of commands I have to use?
It's very simple.
Create a new empty repository in GitHub (without a README or license, you can add them later) and the following screen will show.
In the import code option, paste your Bitbucket repository's URL and voilà!!
You can refer to the GitHub page "Duplicating a repository"
It uses:
git clone --mirror: to clone every references (commits, tags, branches)
git push --mirror: to push everything
That would give:
git clone --mirror https://bitbucket.org/exampleuser/repository-to-mirror.git
# Make a bare mirrored clone of the repository
cd repository-to-mirror.git
git remote set-url --push origin https://github.com/exampleuser/mirrored
# Set the push location to your mirror
git push --mirror
As Noted in the comments by L S:
it is easier to use the Import Code feature from GitHub described by MarMass.
See https://github.com/new/import
Unless... your repo includes a large file: the problem is, the import tool will fail without a clear error message. Only GitHub Support would be able to diagnose what happened.
In case you couldn't find the "Import code" button on GitHub, you can:
Directly open GitHub Importer and enter the URL. It will look like:
Give it a name (or it will import the name automatically)
Select Public or Private repository
Click Begin Import
In May 2016, GitHub announced the ability to "Import repositories with large files".
Se Moving Repository from Bitbucket to GitHub.
This helped me move from one Git provider to another. At the end of it, all the commits were in the destination Git repository. Simple and straightforward.
git remote rename origin bitbucket
git remote add origin https://github.com/edwardaux/Pipelines.git
git push origin master
Once I was happy that the push had been successful to GitHub, I could
delete the old remote by issuing:
git remote rm bitbucket
I had the reverse use case of importing an existing repository from GitHub to Bitbucket.
Bitbucket offers an Import tool as well. The only necessary step is to add URL to repository.
It looks like:
There is the Importing a repository with GitHub Importer
If you have a project hosted on another version control system as Mercurial, you can automatically import it to GitHub using the GitHub Importer tool.
In the upper-right corner of any page, click, and then click Import repository.
Under "Your old repository's clone URL", type the URL of the project you want to import.
Choose your user account or an organization to own the repository, then type a name for the repository on GitHub.
Specify whether the new repository should be public or private.
Public repositories are visible to any user on GitHub, so you can benefit from GitHub's collaborative community.
Public or private repository radio buttonsPrivate repositories are only available to the repository owner, as well as any collaborators you choose to share with.
Review the information you entered, then click Begin import.
You'll receive an email when the repository has been completely imported.
Importing your projects to GitHub
Importing a repository with GitHub Importer
I found this question several months ago when I was trying to do the same thing, and was underwhelmed by the answers given. They all seemed to deal with importing from Bitbucket to GitHub one repository at a time, either via commands issued à la carte, or via the GitHub importer.
I grabulated the code from a GitHub project called gitter and modified it to suite my needs.
You can fork the gist, or take the code from here:
#!/usr/bin/env ruby
require 'fileutils'
# Originally -- Dave Deriso -- deriso#gmail.com
# Contributor -- G. Richard Bellamy -- rbellamy#terradatum.com
# If you contribute, put your name here!
# To get your team ID:
# 1. Go to your GitHub profile, select 'Personal Access Tokens', and create an Access token
# 2. curl -H "Authorization: token <very-long-access-token>" https://api.github.com/orgs/<org-name>/teams
# 3. Find the team name, and grabulate the Team ID
# 4. PROFIT!
#----------------------------------------------------------------------
#your particulars
#access_token = ''
#team_id = ''
#org = ''
#----------------------------------------------------------------------
#the version of this app
#version = "0.2"
#----------------------------------------------------------------------
#some global parameters
#create = false
#add = false
#migrate = false
#debug = false
#done = false
#error = false
#----------------------------------------------------------------------
#fancy schmancy color scheme
class String; def c(cc); "\e[#{cc}m#{self}\e[0m" end end
#200.to_i.times{ |i| print i.to_s.c(i) + " " }; puts
#sep = "-".c(90)*95
#sep_pref = ".".c(90)*95
#sep_thick = "+".c(90)*95
#----------------------------------------------------------------------
# greetings
def hello
puts #sep
puts "BitBucket to GitHub migrator -- v.#{#version}".c(95)
#puts #sep_thick
end
def goodbye
puts #sep
puts "done!".c(95)
puts #sep
exit
end
def puts_title(text)
puts #sep, "#{text}".c(36), #sep
end
#----------------------------------------------------------------------
# helper methods
def get_options
require 'optparse'
n_options = 0
show_options = false
OptionParser.new do |opts|
opts.banner = #sep +"\nUsage: gitter [options]\n".c(36)
opts.version = #version
opts.on('-n', '--name [name]', String, 'Set the name of the new repo') { |value| #repo_name = value; n_options+=1 }
opts.on('-c', '--create', String, 'Create new repo') { #create = true; n_options+=1 }
opts.on('-m', '--migrate', String, 'Migrate the repo') { #migrate = true; n_options+=1 }
opts.on('-a', '--add', String, 'Add repo to team') { #add = true; n_options+=1 }
opts.on('-l', '--language [language]', String, 'Set language of the new repo') { |value| #language = value.strip.downcase; n_options+=1 }
opts.on('-d', '--debug', 'Print commands for inspection, doesn\'t actually run them') { #debug = true; n_options+=1 }
opts.on_tail('-h', '--help', 'Prints this little guide') { show_options = true; n_options+=1 }
#opts = opts
end.parse!
if show_options || n_options == 0
puts #opts
puts "\nExamples:".c(36)
puts 'create new repo: ' + "\t\tgitter -c -l javascript -n node_app".c(93)
puts 'migrate existing to GitHub: ' + "\tgitter -m -n node_app".c(93)
puts 'create repo and migrate to it: ' + "\tgitter -c -m -l javascript -n node_app".c(93)
puts 'create repo, migrate to it, and add it to a team: ' + "\tgitter -c -m -a -l javascript -n node_app".c(93)
puts "\nNotes:".c(36)
puts "Access Token for repo is #{#access_token} - change this on line 13"
puts "Team ID for repo is #{#team_id} - change this on line 14"
puts "Organization for repo is #{#org} - change this on line 15"
puts 'The assumption is that the person running the script has SSH access to Bitbucket,'
puts 'and GitHub, and that if the current directory contains a directory with the same'
puts 'name as the repo to migrated, it will deleted and recreated, or created if it'
puts 'doesn\'t exist - the repo to migrate is mirrored locally, and then created on'
puts 'GitHub and pushed from that local clone.'
puts 'New repos are private by default'
puts "Doesn\'t like symbols for language (ex. use \'c\' instead of \'c++\')"
puts #sep
exit
end
end
#----------------------------------------------------------------------
# git helper methods
def gitter_create(repo)
if #language
%q[curl https://api.github.com/orgs/] + #org + %q[/repos -H "Authorization: token ] + #access_token + %q[" -d '{"name":"] + repo + %q[","private":true,"language":"] + #language + %q["}']
else
%q[curl https://api.github.com/orgs/] + #org + %q[/repos -H "Authorization: token ] + #access_token + %q[" -d '{"name":"] + repo + %q[","private":true}']
end
end
def gitter_add(repo)
if #language
%q[curl https://api.github.com/teams/] + #team_id + %q[/repos/] + #org + %q[/] + repo + %q[ -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ] + #access_token + %q[" -d '{"permission":"pull","language":"] + #language + %q["}']
else
%q[curl https://api.github.com/teams/] + #team_id + %q[/repos/] + #org + %q[/] + repo + %q[ -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ] + #access_token + %q[" -d '{"permission":"pull"}']
end
end
def git_clone_mirror(bitbucket_origin, path)
"git clone --mirror #{bitbucket_origin}"
end
def git_push_mirror(github_origin, path)
"(cd './#{path}' && git push --mirror #{github_origin} && cd ..)"
end
def show_pwd
if #debug
Dir.getwd()
end
end
def git_list_origin(path)
"(cd './#{path}' && git config remote.origin.url && cd ..)"
end
# error checks
def has_repo
File.exist?('.git')
end
def has_repo_or_error(show_error)
#repo_exists = has_repo
if !#repo_exists
puts 'Error: no .git folder in current directory'.c(91) if show_error
#error = true
end
"has repo: #{#repo_exists}"
end
def has_repo_name_or_error(show_error)
#repo_name_exists = !(defined?(#repo_name)).nil?
if !#repo_name_exists
puts 'Error: repo name missing (-n your_name_here)'.c(91) if show_error
#error = true
end
end
#----------------------------------------------------------------------
# main methods
def run(commands)
if #debug
commands.each { |x| puts(x) }
else
commands.each { |x| system(x) }
end
end
def set_globals
puts_title 'Parameters'
#git_bitbucket_origin = "git#bitbucket.org:#{#org}/#{#repo_name}.git"
#git_github_origin = "git#github.com:#{#org}/#{#repo_name}.git"
puts 'debug: ' + #debug.to_s.c(93)
puts 'working in: ' + Dir.pwd.c(93)
puts 'create: ' + #create.to_s.c(93)
puts 'migrate: ' + #migrate.to_s.c(93)
puts 'add: ' + #add.to_s.c(93)
puts 'language: ' + #language.to_s.c(93)
puts 'repo name: '+ #repo_name.to_s.c(93)
puts 'bitbucket: ' + #git_bitbucket_origin.to_s.c(93)
puts 'github: ' + #git_github_origin.to_s.c(93)
puts 'team_id: ' + #team_id.to_s.c(93)
puts 'org: ' + #org.to_s.c(93)
end
def create_repo
puts_title 'Creating'
#error checks
has_repo_name_or_error(true)
goodbye if #error
puts #sep
commands = [
gitter_create(#repo_name)
]
run commands
end
def add_repo
puts_title 'Adding repo to team'
#error checks
has_repo_name_or_error(true)
goodbye if #error
puts #sep
commands = [
gitter_add(#repo_name)
]
run commands
end
def migrate_repo
puts_title "Migrating Repo to #{#repo_provider}"
#error checks
has_repo_name_or_error(true)
goodbye if #error
if Dir.exists?("#{#repo_name}.git")
puts "#{#repo_name} already exists... recursively deleting."
FileUtils.rm_r("#{#repo_name}.git")
end
path = "#{#repo_name}.git"
commands = [
git_clone_mirror(#git_bitbucket_origin, path),
git_list_origin(path),
git_push_mirror(#git_github_origin, path)
]
run commands
end
#----------------------------------------------------------------------
#sequence control
hello
get_options
#do stuff
set_globals
create_repo if #create
migrate_repo if #migrate
add_repo if #add
#peace out
goodbye
Then, to use the script:
# create a list of repos
foo
bar
baz
# execute the script, iterating over your list
while read p; do ./bitbucket-to-github.rb -a -n $p; done<repos
# good enough
In case you want to move your local Git repository to another upstream, you can also do this:
To get the current remote URL:
git remote get-url origin
will show something like:
https://bitbucket.com/git/myrepo
To set new remote repository:
git remote set-url origin git#github.com:folder/myrepo.git
now push contents of current (develop) branch:
git push --set-upstream origin develop
You now have a full copy of the branch in the new remote.
Optionally, return to original git-remote for this local folder:
git remote set-url origin https://bitbucket.com/git/myrepo
It gives the benefit you can now get your new Git repository from GitHub in another folder so that you have two local folders both pointing to the different remotes, the previous (Bitbucket) and the new one both available.
I made the following Bash script in order to clone all of my Bitbucket (user) repositories to GitHub as private repositories.
Requirements:
jq (command-line JSON processor) | macOS: brew install jq
Steps:
Go to Personal access tokens and create an access token. We only need the "repo" scope.
Save the move_me.sh script in a working folder and edit the file as needed.
Don't forget to chmod 755
Run! ./move_me.sh
Enjoy the time you have saved.
Notes:
It will clone the Bitbucket repositories inside the directory the script resides (your working directory).
This script does not delete your Bitbucket repositories.
Need to move to public repositories on GitHub?
Find and change the "private": true to "private": false below.
Moving an organization's repositories?
Check out the developer guide. It's a couple of edits away.
Happy moving.
#!/bin/bash
BB_USERNAME=your_bitbucket_username
BB_PASSWORD=your_bitbucket_password
GH_USERNAME=your_github_username
GH_ACCESS_TOKEN=your_github_access_token
###########################
pagelen=$(curl -s -u $BB_USERNAME:$BB_PASSWORD https://api.bitbucket.org/2.0/repositories/$BB_USERNAME | jq -r '.pagelen')
echo "Total number of pages: $pagelen"
hr () {
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
}
i=1
while [ $i -le $pagelen ]
do
echo
echo "* Processing Page: $i..."
hr
pageval=$(curl -s -u $BB_USERNAME:$BB_PASSWORD https://api.bitbucket.org/2.0/repositories/$BB_USERNAME?page=$i)
next=$(echo $pageval | jq -r '.next')
slugs=($(echo $pageval | jq -r '.values[] | .slug'))
repos=($(echo $pageval | jq -r '.values[] | .links.clone[1].href'))
j=0
for repo in ${repos[#]}
do
echo "$(($j + 1)) = ${repos[$j]}"
slug=${slugs[$j]}
git clone --bare $repo
cd "$slug.git"
echo
echo "* $repo cloned, now creating $slug on GitHub..."
echo
read -r -d '' PAYLOAD <<EOP
{
"name": "$slug",
"description": "$slug - moved from Bitbucket",
"homepage": "https://github.com/$slug",
"private": true
}
EOP
curl -H "Authorization: token $GH_ACCESS_TOKEN" --data "$PAYLOAD" \
https://api.github.com/user/repos
echo
echo "* mirroring $repo to GitHub..."
echo
git push --mirror "git#github.com:$GH_USERNAME/$slug.git"
j=$(( $j + 1 ))
hr
cd ..
done
i=$(( $i + 1 ))
done
Here are the steps to move a private Git repository:
Step 1: Create a GitHub repository
First, create a new private repository on GitHub. It’s important to keep the repository empty, e.g., don’t check option Initialize this repository with a README when creating the repository.
Step 2: Move existing content
Next, we need to fill the GitHub repository with the content from our Bitbucket repository:
Check out the existing repository from Bitbucket:
git clone https://USER#bitbucket.org/USER/PROJECT.git
Add the new GitHub repository as upstream remote of the repository checked out from Bitbucket:
cd PROJECT
git remote add upstream https://github.com:USER/PROJECT.git
Push all branches (below: just master) and tags to the GitHub
repository:
git push upstream master
git push --tags upstream
Step 3: Clean up the old repository
Finally, we need to ensure that developers don’t get confused by having two repositories for the same project. Here is how to delete the Bitbucket repository:
Double-check that the GitHub repository has all content
Go to the web interface of the old Bitbucket repository
Select menu option Setting → Delete repository
Add the URL of the new GitHub repository as the redirect URL
With that, the repository completely settled into its new home at GitHub. Let all the developers know!
Following on from #MarMass' answer, if the GitHub importer is constantly redirecting you to the authentication screen, you'll need to create an App Password in BitBucket in order to import your private repository:
Go to Bitbucket > Personal Settings > App Passwords.
Create an app password with repository read access.
When prompted for your username/password in the GitHub importer, enter your BitBucket username, and the token created above as your password.
After managing to sort out the authentication issue, my imports also errored out with the following message: "There was an error pushing commits to GitHub.".
The issue here, at least for me, was that my GitHub account was set to "Block command line pushes that expose my email", and the repository I was attempting to import from Bitbucket contained commits from my personal email address. After temporarily disabling this setting (GitHub > Settings > Email) I was good to go.
The simplest way of doing it:
git remote rename origin repo_bitbucket
git remote add origin https://github.com/abc/repo.git
git push origin master
Once the push to GitHub is successful, delete the old remote by running:
git remote rm repo_bitbucket