Sometimes your using Azure DevOps for a personal project or something for work and you have a sample that you want to share with the community and you want to copy the code to a github repo so its in the common place for sharing stuff with others. I thought this seemed like it would be quite a common scenario but there didnt really seem to be anything I could find to show you how to do this and I was also surprised when there wasnt any out of the box task I could add to the pipeline which would do it.

I thought id note down what I did incase anyone has a similar scenario.

My scenario was:

  • I have a tool built which I have in my own Azure DevOps repo which ive used for a while and I wanted to share a copy of the code so others could use it and modify their own versions if they want
  • I run a pipeline from my repo which builds the code and gives me the tool to use when I need it
  • I wanted to run a pipeline which would get a copy of the code and then sync it into my repo on GitHub so I can share a new version of the code when I choose

In my case my existing tool was using classic devops pipelines to compile a version of the code and I had a release pipeline which would release it when I needed. I then added a new stage to the pipeline to do the push to github. The original build artifact from my CI pipeline had also included a copy of the code in its zip file but you could equally get it from a repo if needed instead.

If you look at my pipeline stage it looks like below

Once the pipeline runs I have a folder called code in my working directory which will have the copy of the code in it. In the original CI build id taken out anything i didnt want to share such as connection information that might have been in a config file and similar things.

If we look at the git related bits you can see the below yaml snippets show what they do. First off we have the Create Folder for Git.

- bash: |
   mkdir Git
  workingDirectory: '$(System.DefaultWorkingDirectory)'
  displayName: 'Create folder for Git'

This task will create a folder which will be used to sync the existing bit repo into.

Next we have the script which will configure git and copy down the git repo to this new local folder. Notice that the working directory is now the folder I created in the above step.

- bash: |
   git config --global 'Michael Stephenson'
   git config --global ''
   git init
   git remote add origin $GIBHUT_REPO_URL
   git clone $GIBHUT_REPO_URL
  workingDirectory: '$(System.DefaultWorkingDirectory)/Git'
  displayName: 'Clone Github Repo'

The parameter $GIBHUT_REPO_URL can come from your pipeline variables and is just the url to your repo.

Once everything has been copied from Git to this local folder I will then do a delete on everything in the folder:

- task: DeleteFiles@1
  displayName: 'Delete files from $(System.DefaultWorkingDirectory)/Git/IntegrationPlaybook-DataTransformationModeller'
    SourceFolder: '$(System.DefaultWorkingDirectory)/Git/IntegrationPlaybook-DataTransformationModeller'
    Contents: '**/*'

Notice that the folder path is the folder added by the git clone so you will need to be aware of that.

Next ill copy the latest version of the code into this folder from my build artifact.

- task: CopyFiles@2
  displayName: 'Copy Files to: $(System.DefaultWorkingDirectory)/Git/IntegrationPlaybook-DataTransformationModeller'
    SourceFolder: '$(System.DefaultWorkingDirectory)/_DataTransformation.Modeller/drop/code'
    TargetFolder: '$(System.DefaultWorkingDirectory)/Git/IntegrationPlaybook-DataTransformationModeller'

This will mean git will be able to delete, update and add files as required when it pushes changes back to the git repo.

Finally ill use another bash command to add the changes to a commit and push them back to the remote repo.

- bash: |
   cd IntegrationPlaybook-DataTransformationModeller
   git add .
   git status
   git commit -m "$RELEASE_RELEASENAME"
   git push $GITHUB_PUSH_URL
  workingDirectory: '$(System.DefaultWorkingDirectory)/Git'
  displayName: 'Github Commit and Push'

I am pulling in the $RELEASE_RELEASENAME variable from the pipeline so ill know which release updated the files in GitHub.

The other key thing here is the url for the push needs to be configured with your credentials and PAT token for updating github. I set this as the $GITHUB_PUSH_URL variable in my pipeline. You can then choose to make this from keyvault or pipeline variables as you prefer.

The format of the url is:

https://[Github Username]:[Github PAT][GitHub Repo Owner]/[Github Repo Name]

Hopefully this helps someone else out when wanting to share samples and love to hear if anyone has a simpler way to do this as I looked around quite a bit and there didnt seem to be any.


Buy Me A Coffee