Skip to content

Instantly share code, notes, and snippets.

@kerryj89
Last active December 29, 2022 16:27
Show Gist options
  • Save kerryj89/458c4ca76bbf75891741928f9eec839d to your computer and use it in GitHub Desktop.
Save kerryj89/458c4ca76bbf75891741928f9eec839d to your computer and use it in GitHub Desktop.
Migrating from BitBucket Pipelines to Github Actions as of Sept. 25, 2022

Migrating from BitBucket Pipelines to Github Actions as of Sept. 25, 2022

My notes to wrap my head around the similarities and disimilarities between GitHub's and BitBucket's CI system as I migrate over.

Basics:

  • BitBucket Pipelines has a single YAML file <project_root>/bitbucket-pipelines.yml
  • GitHub Actions breaks that apart into multiple YAML files <project_root>/.github/workflows/<whatever>.yml which they call workflows
  • BitBucket Pipelines and GitHub Actions both have a platform where you can easily install and use scripts in your container made by others (or yourself) in a way that abstracts and simplifies your code.
    • BitBucket Pipelines calls these "pipes" (as pipe property) while GitHub Actions calls these "actions" (as uses property).
    # BitBucket Pipelines' SFTP pipe
    ...
    - pipe: atlassian/sftp-deploy:0.5.11
      variables:
        USER: $FTP_USER
        PASSWORD: $FTP_PASSWORD
        SERVER: $FTP_HOST
        REMOTE_PATH: 'public_html/'
        ...
    ...
        
    # GitHub Actions' SFTP action
    ...
    uses: wlixcc/SFTP-Deploy-Action@v1.2.4
    with:
        username: ${{ secrets.FTP_USER }}
        password: ${{ secrets.FTP_PASSWORD }}
        server: ${{ secrets.FTP_HOST }}
        remote_path: 'public_html/'
        ...
    ...
    

Caveats:

  • GitHub Actions doesn't support YAML anchors
    • GitHub Actions uses something called "Composite Actions" instead, which requires you to separate out steps into .github/workflows/actions/<your-action>/action.yml file and import via uses: inside steps:. If you want to import whole workflows, you will need to use "Reusable Workflows" (not shown here).
    • YAML anchor vs. Composite Actions example
    # bitbucket-pipelines.yml
    ...
    definitions:
        gitConfig: &git-config
            >
            git config --global user.name "bitbucket-pipelines";
            git config --global user.email "commits-noreply@bitbucket.org";
    ...
    pipelines:
        pull-requests:
            '**':
                - step:
                    name: YAML anchor example
                    script:
                        - *git-config    
                        - yarn
    ...     
    # Forget the fact that storing a bot user and email as a secret makes no    
    # sense, it's just there to show you how you could pass this info on to the
    # action (actions don't have access to secrets by default as that would be a 
    # security issue if using others actions)
              
    # .github/workflows/some-workflow.yml
    ...
    jobs:
        post-pull-request:
            name: Some workflow
            steps:
                - uses: ./.github/workflows/actions/git-config
                  with:
                    bot_username: ${{ secrets.BOT_USER }}
                    bot_email: ${{ secrets.BOT_EMAIL }}
    ...
    
    # .github/workflows/actions/git-config/action.yml
    name: Git config bot user
    
    inputs:
        bot_username:
            description: Bot username
            required: true
        bot_email:
            description: Bot email
            required: true
    
    runs:
        using: composite
        steps:
            - run: |
                git config --global user.name ${{ inputs.bot_username }}
                git config --global user.email ${{ inputs.bot_email }}
              shell: bash                   
                    
                
  • Note: You will need to end your bash steps with shell: bash inside composite actions.
  • BitBucket Pipelines automatically executes git clone before every step in the pipeline (unless clone flag is disabled); GitHub Actions doesn't and recommends using the uses: actions/checkout statement to do so.
  • actions/checkout only fetches last commit by default; need to set fetch-depth to 0 to fetch all history for all branches and tags.
  • BitBucket Pipelines' pipelines run sequentially by default, whereas GitHub Actions jobs run in parallel (unless configured not to).
    • Not to be confused with steps (both platforms share the same term) which DO run sequentially

Configuration structure:

  • BitBucket has a deep nested config: pipelines → event, branch updated, and/or custom trigger → branch name (if triggered from branch update) → steps.

    # bitbucket-pipelines.yml
    ...
    pipelines:
        pull-requests:
            '**':
                - step:
                    name: Install
                    image: ubuntu-latest
                    script:
                        - npm install
                        - ./some-script.sh
        branches:
            master:
                - step: ...
        custom:
            pull-my-finger:
                - step: ...
  • GitHub Actions breaks what would be BitBucket's pipelines: into two top level properties on and jobs:

    • on → event, branch updated, and/or custom trigger.
    • jobs → job name → steps.
    # pr-all.yml
    ...
    on:
        pull_request:
    
    jobs:
        <whatever-job-name-1>:
            name: Install
            runs-on: ubuntu-latest    
            steps:
                - name: Install dependencies
                run: 
    ...
    # branches-master.yml
    ...
    on:
        push:
            branch:
                - master
    jobs:
        <whatever-job-name-2>:
            - step: ...
    ...
    # custom-pull-my-finger.yml
    ...
    on:
        workflow_dispatch:
        
    jobs:
        pull-my-finger:
            - step: ...
    ...

Environment Variables

  • BitBucket variables | GitHub variables

  • $BITBUCKET_CLONE_DIR$GITHUB_WORKSPACE (Absolute path to cloned directory within container)

  • $BRANCH_NAME$GITHUB_REF_NAME (Name of branch)

  • $BITBUCKET_COMMIT$GITHUB_SHA (Commit hash that triggered the workflow)

Etc

  • You can push back to repo as a GitHub Actions user which makes it a little cleaner to see the automated commits.

    • GitHub's Checkout action creates an auth token that is persisted in the local git config. However, pushing a tag to the repo from a Node script had authentication issues. In order for actions and scripts to see this token, you must pass it through an env configuration:
    ...
        - run: |
            node deployment-script.js
          env:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    ...

    Then, inside your Node script you would use: https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/${process.env.GITHUB_REPOSITORY}.git. For whatever reason, GitHub keeps pointing us to create a PAT (Personal Access Token) just to do this, however, GitHub Actions creates a unique GITHUB_TOKEN just for our workflow that lasts up to 24 hours. They do not advertise x-access-token user, but I see it's use in the wild and for us it's more than adequate. Worse case scenario is that they kill this and we create a PAT. PAT is more secure as you can define access levels.

Helpful Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment