0 Comments

We use multiple build steps in our TeamCity configuration. One build step runs NUnit on our test project dll. If it fails some tests the build status is set to failed but the build step status may not be set to failed (even if process returns 1 – which usually corresponds to failed)!

We use TeamCity Professional 2017.1.3 with the following failure conditions for our configuration:

2017-08-18_14h05_58

And we used the following setting in all subsequent build steps after the NUnit build step:

2017-08-18_14h07_56

We had to change that setting to “Only if build status successful” (thanks to Ahmed on stackoverflow):

2017-08-18_14h11_09

That way we can stop within one build configuration after unit tests fail and before we deploy :).

0 Comments

Today something weird happened: When pulling from one specific repository Git Extensions prompted me for my github login (it did not do that for other repositories). After searching a bit online I came to the solution that I may have used a different URL for cloning. There are two possibilities:

2017-08-14_10h29_30

Using “HTTPS” you will have to enter login and password every time you interact with the remote repository. Using “SSH” will allow Git Extensions to use the private/public key pair you created (and which were used for the other repositories.

To change the settings in Git Extensions go to “Repository” menu –> “Remote repositories…”. There you can change the Url:

2017-08-14_10h24_39

After that everything worked as expected.

0 Comments

If you are using your own domain to send emails, you may get the suspicion that your mails may land in the spam folder of your recipients.

MxToolBox is an easy way to check if your domain (or the IP of your mail server) is listed on a spam list.

With MailRadar you can check if you configured your mail server correctly: not allowing others to use it as a relay server.

0 Comments

 

Auch dieses Jahr war ich wieder bei der Spartakiade in Berlin. Das ist eine Wochenend-Konferenz die aus Workshops besteht. Jeden Tag gibt es ca. 10 verschiedene Workshops.

Am Samstag war ich bei einer Einführung in Angular 4 (Ferdinand Malcher und Johannes Hoppe). Ich hatte letztes Jahr an einem “funky friday” schon mal eine kleine Beispielanwendung mit Angular 2 gebaut. Damals war ich ziemlich erschlagen von der Komplexität der Komponenten (TypeScript, Transpilierung, Konfigurationen), die alle zusammenspielen, um eine Single-Page-Anwendung mit Angular zu bauen. Aus dem Workshop ging ich aber mit einem Gefühl raus die Komplexität deutlich besser verstanden zu haben. Ich würde aber weiterhin Angular nur dann empfehlen, wenn man eine neue, nicht gerade kleine Webpage bauen möchte. Man muss sich in die Struktur reindenken – da macht es keinen Sinn, wenn man nur ab und zu etwas an dem Projekt macht.

Spartakiade 2017 Angular 4

Am Sonntag war ich beim Workshop “.NET in the box” von Frank Pommerening. Ich habe mich da zum ersten Mal ausführlich mit dem Thema Container beschäftigt. Wir probierten mit Docker das Erstellen und Starten von Containern aus. Ich sehe da noch keine sinnvolle Anwendung für unsere Firma, aber eine interessante Technologie.

Insgesamt hat es mir das Wochenende gut gefallen. Wir haben in den Workshops viel an unseren Rechnern programmiert und konfiguriert – das hat Spaß gemacht. Der Service rundum war wieder toll: leckeres, vielfältiges Essen und Trinken, nette Leute :).

Spartakiade 2017 Mittag

0 Comments

Our goal was to append a row to an existing Google Spreadsheet. That spreadsheet is not publicly shared.

The standard scenario seems to be that a user who has access rights interacts with your program and authorizes it to make changes to the spreadsheet. That is not what we needed. In our case an arbitrary user interacts with the website and the server then sends some data to the spreadsheet. The spreadsheet owner is the portal owner, not the interacting user.

There is an easy way to accomplish that: via OAuth for Service Accounts. There is also a Google API client library in .NET for simple communication.

Here is an overview over the steps:

  1. Go to Google APIs and create an API project. Enable Sheets API.
  2. Create Credentials: create Service account key (AppEngine Default Service Account) and save the JSON file with the credentials in your project
  3. Share spreadsheet with Google-API-User, that is the client_email in the downloaded credential JSON file.
  4. Write your code and use the downloaded credentials:

Here is our example code:

using System;
using System.Collections.Generic;
using System.IO;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;

namespace SheetApiTest
{
public class AppendWithGoogleCredentials
{
static string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "Google Sheets API .NET Quickstart";

public void AppendData()
{
// downloaded json file with private key
var credential = GoogleCredential.FromStream(new FileStream("sheets-test.json", FileMode.Open)).CreateScoped(Scopes);

// Create Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});

var spreadsheetId = "11AwV7d1pEPq4x-rx9WeZHNwGJa0ehrCSKyWyfRhh760";
// data to append - must be a value range:
var valueRange = new ValueRange { Values = new List<IList<object>> { new List<object>() } };

// add data for each column
valueRange.Values[0].Add(DateTime.Now.ToLongTimeString());
valueRange.Values[0].Add("b");
valueRange.Values[0].Add("c");

// in append request, the range only requires the name of the table
var rangeToWrite = "Sheet1";
// append request: into first free line
var appendRequest = service.Spreadsheets.Values.Append(valueRange, spreadsheetId, rangeToWrite);
appendRequest.ValueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.USERENTERED;
var appendReponse = appendRequest.Execute();
}
}
}

Have success moving your data!

Anton.