BigW Consortium Gitlab

asana_service.rb 2.67 KB
Newer Older
Jeremy committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
require 'asana'

class AsanaService < Service
  prop_accessor :api_key, :restrict_to_branch
  validates :api_key, presence: true, if: :activated?

  def title
    'Asana'
  end

  def description
    'Asana - Teamwork without email'
  end

  def help
Jeremy committed
16 17 18 19 20
    'This service adds commit messages as comments to Asana tasks.
Once enabled, commit messages are checked for Asana task URLs
(for example, `https://app.asana.com/0/123456/987654`) or task IDs
starting with # (for example, `#987654`). Every task ID found will
get the commit comment added to it.
Jeremy committed
21 22 23

You can also close a task with a message containing: `fix #123456`.

24 25
You can create a Personal Access Token here:
http://app.asana.com/-/account_api'
Jeremy committed
26 27 28 29 30 31 32 33
  end

  def to_param
    'asana'
  end

  def fields
    [
Jeremy committed
34 35 36
      {
        type: 'text',
        name: 'api_key',
37
        placeholder: 'User Personal Access Token. User must have access to task, all comments will be attributed to this user.'
Jeremy committed
38 39 40 41
      },
      {
        type: 'text',
        name: 'restrict_to_branch',
42
        placeholder: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.'
Jeremy committed
43
      }
Jeremy committed
44 45 46
    ]
  end

47 48 49 50
  def supported_events
    %w(push)
  end

51 52 53 54 55 56 57 58
  def client
    @_client ||= begin
      Asana::Client.new do |c|
        c.authentication :access_token, api_key
      end
    end
  end

59
  def execute(data)
60
    return unless supported_events.include?(data[:object_kind])
61

62
    # check the branch restriction is poplulated and branch is not included
63
    branch = Gitlab::Git.ref_name(data[:ref])
Jeremy committed
64
    branch_restriction = restrict_to_branch.to_s
65
    if branch_restriction.length > 0 && branch_restriction.index(branch).nil?
Jeremy committed
66 67 68
      return
    end

69
    user = data[:user_name]
Jeremy committed
70 71
    project_name = project.name_with_namespace

72
    data[:commits].each do |commit|
73
      push_msg = "#{user} pushed to branch #{branch} of #{project_name} ( #{commit[:url]} ):"
74
      check_commit(commit[:message], push_msg)
Jeremy committed
75 76 77 78
    end
  end

  def check_commit(message, push_msg)
79 80 81 82 83 84 85 86 87 88 89 90 91
    # matches either:
    # - #1234
    # - https://app.asana.com/0/0/1234
    # optionally preceded with:
    # - fix/ed/es/ing
    # - close/s/d
    # - closing
    issue_finder = /(fix\w*|clos[ei]\w*+)?\W*(?:https:\/\/app\.asana\.com\/\d+\/\d+\/(\d+)|#(\d+))/i

    message.scan(issue_finder).each do |tuple|
      # tuple will be
      # [ 'fix', 'id_from_url', 'id_from_pound' ]
      taskid = tuple[2] || tuple[1]
Jeremy committed
92

93 94
      begin
        task = Asana::Task.find_by_id(client, taskid)
95 96 97 98 99 100 101
        task.add_comment(text: "#{push_msg} #{message}")

        if tuple[0]
          task.update(completed: true)
        end
      rescue => e
        Rails.logger.error(e.message)
102
        next
Jeremy committed
103 104 105 106
      end
    end
  end
end