asana_service.rb 3.2 KB
Newer Older
J
Jeremy 已提交
1 2 3 4
# == Schema Information
#
# Table name: services
#
5 6 7 8 9 10 11 12 13
#  id         :integer          not null, primary key
#  type       :string(255)
#  title      :string(255)
#  project_id :integer
#  created_at :datetime
#  updated_at :datetime
#  active     :boolean          default(FALSE), not null
#  properties :text
#  template   :boolean          default(FALSE)
14 15 16 17
#  push_events           :boolean          default(TRUE)
#  issues_events         :boolean          default(TRUE)
#  merge_requests_events :boolean          default(TRUE)
#  tag_push_events       :boolean          default(TRUE)
J
Jeremy 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#

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
J
Jeremy 已提交
35 36 37 38 39
    '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.
J
Jeremy 已提交
40 41 42

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

J
Jeremy 已提交
43 44
You can find your Api Keys here:
http://developer.asana.com/documentation/#api_keys'
J
Jeremy 已提交
45 46 47 48 49 50 51 52
  end

  def to_param
    'asana'
  end

  def fields
    [
J
Jeremy 已提交
53 54 55 56 57 58 59 60 61 62 63 64
      {
        type: 'text',
        name: 'api_key',
        placeholder: 'User API token. User must have access to task,
all comments will be attributed to this user.'
      },
      {
        type: 'text',
        name: 'restrict_to_branch',
        placeholder: 'Comma-separated list of branches which will be
automatically inspected. Leave blank to include all branches.'
      }
J
Jeremy 已提交
65 66 67 68
    ]
  end

  def execute(push)
69 70 71
    object_kind = push[:object_kind]
    return unless object_kind == "push"

J
Jeremy 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    Asana.configure do |client|
      client.api_key = api_key
    end

    user = push[:user_name]
    branch = push[:ref].gsub('refs/heads/', '')

    branch_restriction = restrict_to_branch.to_s

    # check the branch restriction is poplulated and branch is not included
    if branch_restriction.length > 0 && branch_restriction.index(branch) == nil
      return
    end

    project_name = project.name_with_namespace
    push_msg = user + ' pushed to branch ' + branch + ' of ' + project_name

    push[:commits].each do |commit|
      check_commit(' ( ' + commit[:url] + ' ): ' + commit[:message], push_msg)
    end
  end

  def check_commit(message, push_msg)
    task_list = []
    close_list = []

    message.split("\n").each do |line|
      # look for a task ID or a full Asana url
      task_list.concat(line.scan(/#(\d+)/))
      task_list.concat(line.scan(/https:\/\/app\.asana\.com\/\d+\/\d+\/(\d+)/))
      # look for a word starting with 'fix' followed by a task ID
      close_list.concat(line.scan(/(fix\w*)\W*#(\d+)/i))
    end

    # post commit to every taskid found
    task_list.each do |taskid|
      task = Asana::Task.find(taskid[0])

      if task
        task.create_story(text: push_msg + ' ' + message)
      end
    end

    # close all tasks that had 'fix(ed/es/ing) #:id' in them
    close_list.each do |taskid|
      task = Asana::Task.find(taskid.last)

      if task
        task.modify(completed: true)
      end
    end
  end
end