Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asana actions cleanup #7

Merged
merged 11 commits into from
Sep 12, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ def self.run(params)
return
end

task_id = Fastlane::Actions::AsanaExtractTaskIdAction.run(task_url: task_url) if task_url
task_id = AsanaExtractTaskIdAction.run(task_url: task_url) if task_url

if template_name.to_s.empty?
text = "#{comment}\n\nWorkflow URL: #{workflow_url}"
create_story(asana_access_token, task_id, text: text)
else
template_file = Helper::DdgAppleAutomationHelper.path_for_asset_file("asana_add_comment/templates/#{template_name}.html")
template_content = Helper::DdgAppleAutomationHelper.load_template_file(template_file)
template_content = Helper::DdgAppleAutomationHelper.load_file(template_file)
return unless template_content

html_text = process_template_content(template_content)
Expand Down Expand Up @@ -96,13 +96,6 @@ def self.validate_params(task_id, task_url, comment, template_name, workflow_url
end
end

def self.load_template_file(template_name)
template_file = Helper::DdgAppleAutomationHelper.path_for_asset_file("asana_add_comment/templates/#{template_name}.html")
File.read(template_file)
rescue StandardError
UI.user_error!("Error: The file '#{template_name}.html' does not exist.")
end

def self.create_story(asana_access_token, task_id, text: nil, html_text: nil)
client = Asana::Client.new do |c|
c.authentication(:access_token, asana_access_token)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require "fastlane/action"
require "fastlane_core/configuration/config_item"
require "httparty"
require "json"
require "asana"
require_relative "../helper/ddg_apple_automation_helper"
require_relative "../helper/github_actions_helper"

Expand All @@ -12,16 +11,20 @@ def self.run(params)
task_id = params[:task_id]
token = params[:asana_access_token]

url = Helper::DdgAppleAutomationHelper::ASANA_API_URL + "/tasks/#{task_id}?opt_fields=assignee"
response = HTTParty.get(url, headers: { 'Authorization' => "Bearer #{token}" })
client = Asana::Client.new do |c|
c.authentication(:access_token, token)
end

if response.success?
assignee_id = response.parsed_response.dig('data', 'assignee', 'gid')
Helper::GitHubActionsHelper.set_output("asana_assignee_id", assignee_id)
assignee_id
else
UI.user_error!("Failed to fetch task assignee: (#{response.code} #{response.message})")
begin
task = client.tasks.get_task(task_gid: task_id)
ayoy marked this conversation as resolved.
Show resolved Hide resolved
rescue StandardError => e
UI.user_error!("Failed to fetch task assignee: #{e}")
return
end

assignee_id = task.assignee["gid"]
Helper::GitHubActionsHelper.set_output("asana_assignee_id", assignee_id)
assignee_id
end

def self.description
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
require "fastlane/action"
require "fastlane_core/configuration/config_item"
require "asana"
require "httparty"
require "json"
require "octokit"
require "time"
require_relative "../helper/ddg_apple_automation_helper"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
require "fastlane/action"
require "fastlane_core/configuration/config_item"
require "httparty"
require "json"
require "time"
require_relative "../helper/ddg_apple_automation_helper"
require_relative "../helper/github_actions_helper"
Expand All @@ -22,16 +20,20 @@ def self.run(params)
# TODO: To be reworked for local execution.
AsanaExtractTaskAssigneeAction.run(task_id: task_id, asana_access_token: token)

url = Helper::DdgAppleAutomationHelper::ASANA_API_URL + "/tasks/#{task_id}/subtasks?opt_fields=name,created_at"
response = HTTParty.get(url, headers: { 'Authorization' => "Bearer #{token}" })
asana_client = Asana::Client.new do |c|
c.authentication(:access_token, token)
end

if response.success?
automation_subtask_id = find_oldest_automation_subtask(response)
Helper::GitHubActionsHelper.set_output("asana_automation_task_id", automation_subtask_id)
automation_subtask_id
else
UI.user_error!("Failed to fetch 'Automation' subtask: (#{response.code} #{response.message})")
begin
subtasks = asana_client.tasks.get_subtasks_for_task(task_gid: task_id, options: { fields: ["name", "created_at"] })
rescue StandardError => e
UI.user_error!("Failed to fetch 'Automation' subtasks for task #{task_id}: #{e}")
return
end

automation_subtask_id = find_oldest_automation_subtask(subtasks)&.gid
Helper::GitHubActionsHelper.set_output("asana_automation_task_id", automation_subtask_id)
automation_subtask_id
end

def self.description
Expand Down Expand Up @@ -65,11 +67,10 @@ def self.is_supported?(platform)
true
end

def self.find_oldest_automation_subtask(response)
response.parsed_response['data']
&.find_all { |hash| hash['name'] == 'Automation' }
&.min_by { |x| Time.parse(x['created_at']) } # Get the oldest 'Automation' subtask
&.dig('gid')
def self.find_oldest_automation_subtask(subtasks)
subtasks
.find_all { |task| task.name == 'Automation' }
&.min_by { |task| Time.parse(task.created_at) }
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "fastlane/action"
require "fastlane_core/configuration/config_item"
require "httparty"
require "asana"
require_relative "../helper/ddg_apple_automation_helper"

module Fastlane
Expand All @@ -11,18 +11,15 @@ def self.run(params)
token = params[:asana_access_token]
file_name = params[:file_name]

begin
file = File.open(file_name)
url = Helper::DdgAppleAutomationHelper::ASANA_API_URL + "/tasks/#{task_id}/attachments"
response = HTTParty.post(url,
headers: { 'Authorization' => "Bearer #{token}" },
body: { file: file })
asana_client = Asana::Client.new do |c|
c.authentication(:access_token, token)
end

unless response.success?
UI.user_error!("Failed to upload file to Asana task: (#{response.code} #{response.message})")
end
rescue StandardError
UI.user_error!("Failed to open file: #{file_name}")
begin
asana_client.tasks.find_by_id(task_id).attach(filename: file_name, mime: "application/octet-stream")
rescue StandardError => e
UI.user_error!("Failed to upload file to Asana task: #{e}")
return
end
end

Expand Down Expand Up @@ -51,7 +48,7 @@ def self.available_options
optional: false,
type: String),
FastlaneCore::ConfigItem.new(key: :file_name,
description: "Path to the file that will be uploaded",
description: "Path to a file that will be uploaded",
ayoy marked this conversation as resolved.
Show resolved Hide resolved
optional: false,
type: String)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module Fastlane

module Helper
class DdgAppleAutomationHelper
ASANA_API_URL = "https://app.asana.com/api/1.0"
ASANA_APP_URL = "https://app.asana.com/0/0"
ERROR_ASANA_ACCESS_TOKEN_NOT_SET = "ASANA_ACCESS_TOKEN is not set"
ERROR_GITHUB_TOKEN_NOT_SET = "GITHUB_TOKEN is not set"
Expand All @@ -23,10 +22,10 @@ def self.path_for_asset_file(file)
File.expand_path("../assets/#{file}", __dir__)
end

def self.load_template_file(template_file)
File.read(template_file)
def self.load_file(file)
File.read(file)
rescue StandardError
UI.user_error!("Error: The file '#{template_file}' does not exist.")
UI.user_error!("Error: The file '#{file}' does not exist.")
end
end
end
Expand Down
File renamed without changes.
40 changes: 40 additions & 0 deletions spec/asana_extract_task_assignee_action_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
describe Fastlane::Actions::AsanaExtractTaskAssigneeAction do
describe "#run" do
before do
@asana_client_tasks = double
asana_client = double("asana_client")
allow(Asana::Client).to receive(:new).and_return(asana_client)
allow(asana_client).to receive(:tasks).and_return(@asana_client_tasks)
allow(@asana_client_tasks).to receive(:get_task)
end

it "returns the assignee ID and sets GHA output when Asana task is assigned" do
allow(Fastlane::Helper::GitHubActionsHelper).to receive(:set_output)
expect(@asana_client_tasks).to receive(:get_task).and_return(
double(assignee: { "gid" => "67890" })
)

expect(test_action("12345")).to eq("67890")
expect(Fastlane::Helper::GitHubActionsHelper).to have_received(:set_output).with("asana_assignee_id", "67890")
end

it "returns nil when Asana task is not assigned" do
expect(@asana_client_tasks).to receive(:get_task).and_return(
double(assignee: { "gid" => nil })
)

expect(test_action("12345")).to eq(nil)
end

it "shows error when failed to fetch task assignee" do
expect(@asana_client_tasks).to receive(:get_task).and_raise(StandardError, "API error")
expect(Fastlane::UI).to receive(:user_error!).with("Failed to fetch task assignee: API error")

test_action("12345")
end
end

def test_action(task_id)
Fastlane::Actions::AsanaExtractTaskAssigneeAction.run(task_id: task_id)
end
end
57 changes: 0 additions & 57 deletions spec/asana_extract_task_assignee_spec.rb

This file was deleted.

2 changes: 1 addition & 1 deletion spec/asana_find_release_task_action_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ def validate_semver(version)
end

it "shows error" do
allow(Fastlane::UI).to receive(:user_error!)
expect(Fastlane::Actions::AsanaFindReleaseTaskAction).not_to receive(:find_hotfix_task_in_response)
expect(Fastlane::Actions::AsanaFindReleaseTaskAction).not_to receive(:find_release_task_in_response)
allow(Fastlane::UI).to receive(:user_error!)

find_release_task("1.0.0")

Expand Down
45 changes: 45 additions & 0 deletions spec/asana_get_release_automation_subtask_id_action_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
describe Fastlane::Actions::AsanaGetReleaseAutomationSubtaskIdAction do
describe "#run" do
before do
@asana_client_tasks = double
asana_client = double("asana_client")
allow(Asana::Client).to receive(:new).and_return(asana_client)
allow(asana_client).to receive(:tasks).and_return(@asana_client_tasks)
allow(@asana_client_tasks).to receive(:get_subtasks_for_task)
end
it "returns the 'Automation' subtask ID and sets GHA output when the subtask exists in the Asana task" do
allow(Fastlane::Helper::GitHubActionsHelper).to receive(:set_output)
expect(Fastlane::Actions::AsanaExtractTaskAssigneeAction).to receive(:run)
expect(@asana_client_tasks).to receive(:get_subtasks_for_task).and_return(
[double(gid: "12345", name: "Automation", created_at: "2020-01-01T00:00:00.000Z")]
)

expect(test_action("https://app.asana.com/0/0/0")).to eq("12345")
expect(Fastlane::Helper::GitHubActionsHelper).to have_received(:set_output).with("asana_automation_task_id", "12345")
end

it "returns the oldest 'Automation' subtask when there are multiple subtasks with that name" do
expect(Fastlane::Actions::AsanaExtractTaskAssigneeAction).to receive(:run)
expect(@asana_client_tasks).to receive(:get_subtasks_for_task).and_return(
[double(gid: "12345", name: "Automation", created_at: "2020-01-01T00:00:00.000Z"),
double(gid: "431", name: "Automation", created_at: "2019-01-01T00:00:00.000Z"),
double(gid: "12460", name: "Automation", created_at: "2020-01-05T00:00:00.000Z")]
)

expect(test_action("https://app.asana.com/0/0/0")).to eq("431")
end

it "returns nil when 'Automation' subtask does not exist in the Asana task" do
allow(Fastlane::UI).to receive(:user_error!)
expect(Fastlane::Actions::AsanaExtractTaskAssigneeAction).to receive(:run)
expect(@asana_client_tasks).to receive(:get_subtasks_for_task).and_raise(StandardError, "API error")

test_action("https://app.asana.com/0/0/0")
expect(Fastlane::UI).to have_received(:user_error!).with("Failed to fetch 'Automation' subtasks for task 0: API error")
end
end

def test_action(task_url)
Fastlane::Actions::AsanaGetReleaseAutomationSubtaskIdAction.run(task_url: task_url)
end
end
Loading