I use Jenkins pipeline to build app. In pipeline I invoke fastlane lanes two times, between them I invoke integration tests.
This is the script for iOS
default_platform(:ios)
before_all do |lane, options|
IPA_NAME = options[:ipa_name];
ENV["SLACK_URL"] = "slack_url";
ENV["DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS"] = "-t DAV"
end
platform :ios do
lane :build_to_browserstack do |lane, options|
begin
build_app()
push_to_browserstack()
rescue => exception
error_do_all_operations(exception)
end
end
end
platform :ios do
lane :push_to_testflight do |lane, options|
begin
push_to_testflight_and_s3()
passed_do_all_operations()
rescue => exception
error_do_all_operations(exception)
end
end
end
def build_app
clean_build_artifacts
cert
sigh(
skip_install: true,
provisioning_name: 'name'
)
increment_version_number(
version_number: "1.22.3"
)
increment_build_number({
build_number: latest_testflight_build_number + 1
})
get_version_number(
target: ENV["SCHEME"]
)
get_build_number
gym(
scheme: ENV["SCHEME"],
export_options: {
provisioningProfiles: {
"com.com.com" => "profile"
}
},
output_name: IPA_NAME
)
end
def push_to_browserstack
upload_to_browserstack_app_automate(
browserstack_username: "name",
browserstack_access_key: "key",
file_path: ENV["PATH_TO_IPA"] + IPA_NAME,
custom_id: IPA_NAME
)
end
def push_to_testflight_and_s3
upload_to_testflight(
ipa: ENV["PATH_TO_IPA"] + IPA_NAME,
skip_submission: true,
skip_waiting_for_build_processing: true,
team_name: 'team'
)
aws_s3(
access_key: 'key',
secret_access_key: 'key',
bucket: 'bucket',
region: 'us-east-2',
ipa: ENV["PATH_TO_IPA"] + IPA_NAME,
path: 'path'
)
end
def passed_do_all_operations
slack(
message: "New iOS build was uploaded to TestFlight",
success: true,
channel: "#engineering_general",
slack_url: ENV["SLACK_URL"],
default_payloads: [:git_branch],
payload: {"Build Date" => Time.new.to_s,},
attachment_properties: {
fields: [
{
title: "Version number",
value: lane_context[SharedValues::VERSION_NUMBER],
},
{
title: "Build number",
value: lane_context[SharedValues::BUILD_NUMBER],
}
]
}
)
end
def error_do_all_operations(exception)
slack(
message: "iOS build was not uploaded to TestFlight",
success: false,
channel: "#engineering_general",
slack_url: ENV["SLACK_URL"],
default_payloads: [:git_branch],
payload: {"Build Date" => Time.new.to_s,},
attachment_properties: {
fields: [
{
title: "Version number",
value: lane_context[SharedValues::VERSION_NUMBER],
},
{
title: "Build number",
value: lane_context[SharedValues::BUILD_NUMBER],
},
{
title: "Error message",
value: exception.to_s,
short: false
}
]
}
)
end
I use parameterized invocation of fastlane, peace of code:
before_all do |lane, options|
IPA_NAME = options[:ipa_name];
At first I invoke the lane build_to_browserstack. Now it has error due to my browserstack accout, and error_do_all_operations() function produces slack notification correctly, with values of lane_context[SharedValues::VERSION_NUMBER], and lane_context[SharedValues::BUILD_NUMBER],
At second I invoke the lane push_to_testflight and here is a problem. Function passed_do_all_operations() produces slack notifications without lane_context values.
So the question is how to pass lane_context from first invocation to second invocation ?
Related
I would like to find a solution to my problem: I have a subscription from external service that send a lot of information that I need to save on mongoDB and get the stored in a dashboard. Before to insert them I need to find if exist and update instead create.
This is my code:
await ProjectModel.findOne( { address } ).then( project => {
if( project ) {
project.tasked?.push( task )
const index = ( project.owners as TypeOwners ).findIndex( ( p ) => p.owner === task.owner )
if( index >= 0 && project.owners ) {
project.owners[index].amount++
project.owners[index].tasks.push( task.address )
project.markModified('owners');
} else {
project.owners?.push( {
tasks: [ task.address ],
amount: 1,
owner: task?.owner
} )
}
project?.save()
console.log( `updated: ${address}` )
} else {
ProjectModel.create( {
cm_address: cm_address,
platform: platform,
project_symbol: symbol,
project_collection:name,
creator: creators as Creator[],
description: description,
tasked: [ tasked ],
owners: [ {
tasks: [ task.address ],
amount: 1,
owner: task?.owner
}]
})
console.log( `created: ${address}` )
}
})
The problem is some time the information received are simultaneous and don't give the time to mongodb to check if exist and duplicate the record (instead of update) and some time I receive this error:
VersionError: No matching document found for id "XXXXXXXX" version 0 modifiedPaths ....
Someone have a solution for this situation? Thank you :slight_smile:
I have the following AWS CDK configuration in TypeScript (abriged):
const jobProps = {
command: {
name: 'glueetl',
pythonVersion: '3',
scriptLocation: `s3://${s3bucket.bucketName}/${this.scriptName}`,
},
connections: { connections: [connectionName] },
defaultArguments: { },
description: idEnv + '-job',
executionProperty: {
maxConcurrentRuns: 1,
},
glueVersion: '2.0',
maxRetries: 0,
name: idEnv + '-job',
numberOfWorkers: 2,
role: glueServiceRole.roleArn,
timeout: 180, // minutes
workerType: 'Standard',
};
const job = new CfnJob(this, idEnv, jobProps);
const trigger = new CfnTrigger(this, idEnv + '-trigger', {
type: 'SCHEDULED',
description: 'Scheduled run for ' + job.name,
schedule: this.JOB_SCHEDULE,
actions: [
{
jobName: job.name,
},
],
});
The trigger is created, it is seen in the Console and it is linked to the Job. But it just won't run (manual Job run is OK). What am I missing?
You need to add "startOnCreation: true" to the CfnTrigger props, so the trigger status will be enabled by default.
I am trying to integrate the Payment Request API for the Google Pay for Payments using javascript but my code returns a PaymentRequest is not defined error.
Here is my code.
CODE:
const supportedInstruments = [
{
supportedMethods: ['https://tez.google.com/pay'],
data: {
pa: 'abc#gmail.com',
pn: 'abc',
tr: '1234ABCD', // your custom transaction reference ID
url: 'http://url/of/the/order/in/your/website',
mc: '1234', // your merchant category code
tn: 'Purchase in Merchant',
},
}
];
const details = {
total: {
label: 'Total',
amount: {
currency: 'INR',
value: '10.01', // sample amount
},
},
displayItems: [{
label: 'Original Amount',
amount: {
currency: 'INR',
value: '10.01',
},
}],
};
let request = null;
try {
request = new PaymentRequest(supportedInstruments, details);
}
catch (e) {
console.log('Payment Request Error: ' + e.message);
return;
}
if (!request) {
console.log('Web payments are not supported in this browser.');
return;
}
Error Message:
Payment Request Error: PaymentRequest is not defined
Sounds to me like you are testing it in an older browser that simply doesn't support it. Browser support is pretty good these days, but not universal. You just need to do a simple bit of feature detection and wrap your code in an if statement to check the browser supports it:
if (window.PaymentRequest) {
// your payment request code here
}
I have a job to push some values to consul based on user parameters and 2 values are generated when the pipeline is run like shutdown_date and termination_date:
def now, shutdown_date, termination_date
pipeline {
parameters {
string(name: 'env', defaultValue: 'abc')
string(name: 'owr', defaultValue: 'abc')
string(name: 'de', defaultValue: 'abc')
string(name: 'tct', defaultValue: 'abc-123')
}
agent { label 'abc' }
stages {
stage ('Update ENV'){
steps {
script {
now = new Date()
println now.format("yyyy-MM-dd", TimeZone.getTimeZone('UTC'))
shutdown_date = now + 170
shutdown_date = (shutdown_date.format("yyyy-MM-dd", TimeZone.getTimeZone('UTC'))).trim()
println shutdown_date
termination_date = now + 365
termination_date = (termination_date.format("yyyy-MM-dd", TimeZone.getTimeZone('UTC'))).trim()
println termination_date
step([$class: 'ConsulKVBuilder', aclToken: '', apiUri: '', debugMode: 'DISABLED', envVarKey: 'env_status', hostUrl: '', key: 'env_status/${env_name}', keyValue: '{ "owr":"${owr}", "de":"${de}", "tct":"${tct}", "shutdown_date": "${shutdown_date}", "termination_date": "${termination_date}" }', requestMode: 'WRITE'])
}
}
}
}
}
Expected result:
{ "owr":"abc", "de":"abc", "tct":"abc-123", "shutdown_date": "2020-02-15", "termination_date": "2020-08-15" }
Actual result:
{ "owr":"abc", "de":"abc", "tct":"abc-123", "shutdown_date": "${shutdown_date}", "termination_date": "${termination_date}" }
As mentioned in this answer, single-quoted strings won't interpolate variables.
You need to change your step to use double quotes and escape the ones in json.
step([$class: 'ConsulKVBuilder', aclToken: '', apiUri: '', debugMode: 'DISABLED', envVarKey: 'env_status', hostUrl: '', key: "env_status/${env_name}", keyValue: "{ \"owr\":\"${owr}\", \"de\":\"${de}\", \"tct\":\"${tct}\", \"shutdown_date\": \"${shutdown_date}\", \"termination_date\": \"${termination_date}\" }", requestMode: 'WRITE'])
String interpolation
How do I write a message to Mattermost using Fastlane ?
Below is my trial. I got most from this link.
What is still wrong ?
(of course, I replaced the MATTERMOST_WEBHOOK_URL by the actual value that I established in Mattermost).
In the link above, I saw an actions folder with a mattermost.rb file
How do I get this action to work ? What do I need to do inside my Fastfile or anywhere in order to get this to work ?
In fact, running the fastlane send_message lane, I get a success. But unfortunately, nothing is visible in my Mattermost channel.
Inside my Fastfile, I do:
def send_message_to_mattermost(options)
unless ENV['MATTERMOST_WEBHOOK_URL'].nil? || ENV['MATTERMOST_WEBHOOK_URL'].empty?
mattermost(
pretext: options[:pretext],
message: options[:msg],
default_payloads: options[:default_payloads],
username: 'Fastlane',
icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
payload: {},
attachment_properties: {
title: options[:title],
thumb_url: options[:thumb_url],
fields: [{
title: 'Version',
value: options[:version_number],
short: true
},
{
title: 'Build Number',
value: options[:build_number],
short: true
},
{
title: 'Built by',
value: 'Jenkins',
short: true
}]
},
success: options[:success]
)
end
end
And my Fastlane lane looks like this:
lane :send_message do
send_message_to_mattermost({
:version_number => ENV['VERSION_NUMBER'],
:build_number => ENV["BUILD_NUMBER"],
:pretext => ENV['MAIN_APP_IDENTIFIER'],
:title => 'Unsuccessful Build',
:thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
:msg => "My message...",
:default_payloads => [:lane],
:success => true
})
end
Is mattermost(...) a standard command in Fastlane ? If not what do I need to do in order to send information to a Mattermost channel from Fastlane ?
I finally found a solution.
What was missing is to set the ENV["MATTERMOST_WEBHOOK_URL"] upfront
before_all do
ENV["MATTERMOST_WEBHOOK_URL"] = 'https://my_new_webooh_from_mattermost'
end
...and leave the following code intact (i.e. do not replace 'MATTERMOST_WEBHOOK_URL' by anything else - the before_all does the trick...)
def send_message_to_mattermost(options)
unless ENV['MATTERMOST_WEBHOOK_URL'].nil? || ENV['MATTERMOST_WEBHOOK_URL'].empty?
mattermost(
pretext: options[:pretext],
message: options[:msg],
default_payloads: options[:default_payloads],
username: 'Fastlane',
icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
payload: {},
attachment_properties: {
title: options[:title],
thumb_url: options[:thumb_url],
fields: [{
title: 'Version',
value: options[:version_number],
short: true
},
{
title: 'Build Number',
value: options[:build_number],
short: true
},
{
title: 'Built by',
value: 'Jenkins',
short: true
}]
},
success: options[:success]
)
end
end