GitVision Workshop: Transforming GitHub Commits into Eurovision Playlists

A fun tool that turns your GitHub code into Eurovision music during our 2-hour hands-on workshop. Code + Music = Fun!

What We'll Build Today

Flutter App with GitHub Integration

Analyze commit patterns and developer coding style

AI-Powered Eurovision Recommendations

Match coding moods with iconic Eurovision songs

Spotify Integration

Turn recommendations into playable playlists

Social Sharing

Share your coding soundtrack with the world

2

We Are Developers 2025

Learning Objectives

Technical Skills

  • Multi-API integration architecture
  • AI engineering and response parsing
  • Asynchronous state management

Practical Experience

  • Building production-ready error handling
  • Implementing intelligent fallback strategies
  • Optimizing performance in multi-API applications


3

We Are Developers 2025

GitHub Copilot Chat Configuration Menu

Explore the versatile configuration options within GitHub Copilot to customize its behavior and optimize your development workflow.

1

Prompt Files

Manage and create custom .prompt.md files for tailored Copilot interactions, stored in .github/prompts/.

2

Instructions

Configure global coding style, documentation, and testing guidelines for Copilot, typically in .github/copilot-instructions.md.

3

Tool Sets

Define and customize which tools Copilot can access in agent mode, such as codebase navigation, terminal, or web search.

4

Modes

Switch between interaction modes like "Ask" (Q&A) or "Agent" (autonomous task execution) to control Copilot's actions.

5

MCP Servers

Connect to custom model servers, configure parameters, and adjust context settings for enterprise-specific Copilot deployments.

6

Generate Instructions

Automatically analyze your codebase to create instruction templates, helping establish consistent coding standards effortlessly.

7

Chat Settings

Access general settings for the Copilot Chat interface, including visual preferences, auto-completion, and context inclusion.

4

We Are Developers 2025

Technical Prerequisites & Architecture

Prerequisites

  • Flutter/Dart basics (widgets, async/await, HTTP requests)
  • REST API concepts and JSON parsing
  • GitHub and Spotify developer accounts
  • 8GB+ RAM, stable internet connection

Data Flow Architecture

GitHub Commits

Extract commit history and message content

Sentiment Analysis

Process commit messages for emotional context

AI Prompt

Match commit patterns to Eurovision songs

Spotify Integration

Create playable playlists from recommendations

5

We Are Developers 2025

Workshop Structure

1

Phase 1: GitHub Integration (35 min)

Connect to GitHub API and analyze commit patterns

2

Phase 2: AI Eurovision Magic (40 min)

Use AI to match commits with Eurovision songs

3

Phase 3: Spotify Integration (35 min)

Make playlists playable with Spotify

4

Phase 4: Social Sharing (25 min)

Add sharing features and analytics

5

Phase 5: Production Polish (15 min)

Error handling and performance optimization

Flow suggestions but this is your time!

6

We Are Developers 2025

Step 1 - Launch Development Environment

1

Launch Codespace

Click the button: No fork needed. Uses the workshop's minutes, not yours.

2

Verify Environment

Ensure the `gitvision` project loads. Flutter & Dart should already be installed.

Tip: Refresh if Codespace stalls during initialization.

7

We Are Developers 2025

Step 2 - Initial Setup

Commands to Run:

cd gitvision
chmod +x workshop-start.sh
./workshop-start.sh

This script will:

  • Install required dependencies
  • Set up API configuration templates
  • Prepare the Flutter environment

You'll see a success message when the setup is complete.

8

We Are Developers 2025

Step 3 - Configure API Keys

Edit lib/config/api_tokens.dart with your credentials:

static const String githubModelsToken = "your_token_here"; 
static const String spotifyClientId = "your_client_id";

Where to get tokens:

  • GitHub: Use your personal access token with repo scope
  • Spotify: Create a free developer application at developer.spotify.com


9

We Are Developers 2025

Step 4 - Launch The App

Run the app in web mode for the best workshop experience:

flutter run -d web-server

The app will open in your default browser at localhost:8080

  • Verify the app loads correctly
  • Check that the GitHub username input appears
  • Try a test username to ensure connectivity

💡 You can also test the app using the iOS emulator if you have it installed:

  1. Open the iOS Simulator from the Xcode menu
  1. In your terminal, run flutter run -d ios
  1. The app will launch in the iOS Simulator for you to test


10

We Are Developers 2025

Phase 1: GitHub Integration

What We're Building

In this phase, we'll connect to GitHub and analyze commit patterns to detect the developer's coding "vibe".

GitHub API Integration

Securely connect to GitHub and fetch commit history

Commit Analysis

Extract and analyze commit messages for sentiment

Eurovision Vibe Matching

Map commit patterns to Eurovision song categories

11

We Are Developers 2025

Phase 1: Key Files

Main Implementation Files:

  • lib/main.dart - Basic UI structure and GitHub integration skeleton
  • lib/models/commit.dart - Commit data structure
  • lib/config/api_tokens.dart - API configuration template

Files You'll Complete:

  • lib/services/github_service.dart - GitHub API wrapper with error handling
  • lib/sentiment_analyzer.dart - Eurovision mood detection logic

Your Phase 1 Tasks:

  1. Test existing GitHub integration with error scenarios
  1. Implement comprehensive GitHub API error handling
  1. Complete sentiment analysis keyword mapping
  1. Add rate limiting and retry logic

12

We Are Developers 2025

Phase 1: Implementation Steps

Test GitHub Integration

Enter valid and invalid GitHub usernames in the app. Success criteria: API returns 200 status code, correctly displays commit list, and handles 404 errors gracefully.

Explore Sentiment Analysis

Open lib/sentiment_analyzer.dart to review keyword → Eurovision vibe mapping and understand the detectVibe() method.

Add Error Handling

Implement comprehensive error handling with specific error types: RateLimitException, UserNotFoundException, and NetworkException in the GitHub service.

Test Your Changes

Verify that error handling works by testing with invalid usernames and simulating rate limit errors. Success criteria: User sees friendly messages for all error scenarios.

13

We Are Developers 2025

Commit Message Analysis

How We Detect Eurovision Vibes:

// Excerpt from sentiment_analyzer.dart // Analyze commit messages and return the detected vibe static String detectVibe(List commitMessages) { if (commitMessages.isEmpty) { return 'Productive'; // Default vibe } // This map defines the keywords for each vibe const Map> vibeKeywords = { 'Productive': ['add', 'implement', 'feature', 'improve', 'optimize', 'refactor'], 'Intense': ['fix', 'bug', 'issue', 'error', 'crash', 'hotfix'], 'Creative': ['design', 'style', 'ui', 'ux', 'animation', 'visual'], // ... and so on for other vibes }; // Count occurrences of keywords for each vibe Map vibeCounts = {}; for (String vibe in vibeKeywords.keys) { vibeCounts[vibe] = 0; } for (String message in commitMessages) { String lowerMessage = message.toLowerCase(); for (String vibe in vibeKeywords.keys) { for (String keyword in vibeKeywords[vibe]!) { if (lowerMessage.contains(keyword.toLowerCase())) { vibeCounts[vibe] = (vibeCounts[vibe] ?? 0) + 1; } } } }

// Excerpt from sentiment_analyzer.dart // Analyze commit messages and return the detected vibe static String detectVibe(List<String> commitMessages) { if (commitMessages.isEmpty) { return 'Productive'; // Default vibe } // This map defines the keywords for each vibe const Map<String, List<String>> vibeKeywords = { 'Productive': ['add', 'implement', 'feature', 'improve', 'optimize', 'refactor'], 'Intense': ['fix', 'bug', 'issue', 'error', 'crash', 'hotfix'], 'Creative': ['design', 'style', 'ui', 'ux', 'animation', 'visual'], // ... and so on for other vibes }; // Count occurrences of keywords for each vibe Map<String, int> vibeCounts = {}; for (String vibe in vibeKeywords.keys) { vibeCounts[vibe] = 0; } for (String message in commitMessages) { String lowerMessage = message.toLowerCase(); for (String vibe in vibeKeywords.keys) { for (String keyword in vibeKeywords[vibe]!) { if (lowerMessage.contains(keyword.toLowerCase())) { vibeCounts[vibe] = (vibeCounts[vibe] ?? 0) + 1; } } } }

14

We Are Developers 2025

Phase 2: AI Eurovision Magic

What We're Building

In this phase, we'll use AI to intelligently match GitHub commit patterns with Eurovision songs.

AI Models API Integration

Connect to AI services to analyze commit patterns

Eurovision-Specific Prompts

Craft specialized prompts with Eurovision context

Song Data Parsing

Extract structured song recommendations from AI responses

Fallback System

Ensure recommendations even when AI services fail

15

We Are Developers 2025

Phase 2: AI Implementation

Let's explore how we'll implement AI in our Eurovision playlist generator:

GitHub Models API

We're using GPT-4.1 via GitHub Models with the endpoint: https://models.github.ai/inference

Authentication is handled through your GitHub token.

Prompt Engineering

Our strategy includes providing context (relevant commit history and patterns), defining the task (requesting Eurovision song matches based on vibe), and specifying format (JSON response with song, artist, year).

Response Handling

We'll parse the AI's JSON responses to extract structured song recommendations that match the development vibe detected from your commits.

16

We Are Developers 2025

Phase 2: Key Files

Implementation Files:

  • lib/services/ai_playlist_service.dart - AI playlist generation
  • lib/models/eurovision_song.dart - Song data model
  • lib/prompts/eurovision_prompts.dart - AI prompt templates

Your Phase 2 Tasks:

  1. Complete the generateEurovisionPlaylist() method
  1. Enhance Eurovision song model validation
  1. Test AI responses and implement error handling

17

We Are Developers 2025

Live Coding: AI Prompt Builder 💻

String _buildEurovisionPrompt(SentimentResult sentiment) {
  return '''
Based on coding mood: "${sentiment.mood}" (${sentiment.confidence} confidence)

Suggest 5 Eurovision songs matching this developer vibe:
- Different years and countries
- Match energy/theme to coding mood  
- Include reasoning for each choice

JSON format: [{"title":"", "artist":"", "country":"", "year":2024, "reasoning":""}]

Commit keywords: ${sentiment.keywords.join(', ')}
''';
}

18

We Are Developers 2025

GitHub Models API Implementation 🔌


Future<String> _callGitHubModelsAPI(String prompt) async {
  final response = await http.post(
    Uri.parse('https://models.github.ai/inference/chat/completions'),
    headers: {
      'Authorization': 'Bearer ${ApiConfig.githubToken}',
      'Content-Type': 'application/json',
    },
    body: jsonEncode({
      'messages': [
        {'role': 'system', 'content': 'Eurovision expert & music curator'},
        {'role': 'user', 'content': prompt}
      ],
      'model': 'openai/gpt-4.1',
      'temperature': 0.7, // Balance creativity + consistency
    }),
  );
  // ... error handling
}

19

We Are Developers 2025

AI Response Handling

Parsing AI Responses

// In ai_playlist_service.dart
List<EurovisionSong> _parseAIResponse(String response) {
  try {
    // Extract JSON from AI response (handles non-JSON text)
    final jsonMatch = RegExp(r'\[[\s\S]*\]').firstMatch(response);
    if (jsonMatch == null) {
      throw FormatException('No JSON array found in response');
    }
    
    final jsonString = jsonMatch.group(0);
    final List songsList = jsonDecode(jsonString);
    
    return songsList
        .map((song) => EurovisionSong.fromJson(song))
        .toList();
  } catch (e) {
    // Handle parsing errors gracefully
    print('Error parsing AI response: $e');
    return _getFallbackSongs();
  }
}

Eurovision Song Model

// In eurovision_song.dart
class EurovisionSong {
  final String title;
  final String artist;
  final String country;
  final int year;
  final String reasoning;
  
  // Constructor and validation
  EurovisionSong({
    required this.title,
    required this.artist,
    required this.country,
    required this.year,
    required this.reasoning,
  }) : assert(year >= 1956 && year <= 2025);
  
  // JSON parsing methods
  factory EurovisionSong.fromJson(Map json) {...}
}

20

We Are Developers 2025

Phase 3: Spotify Integration

What We're Building

In this phase, we'll connect to Spotify to make our Eurovision recommendations playable.

OAuth Authentication

Implement secure Spotify authentication flow

Song Search

Find Eurovision songs on Spotify with fallback strategies

Playable Interface

Create an interactive playlist with play controls

Graceful Fallbacks

Handle missing tracks and API limitations

21

We Are Developers 2025

Eurovision Song Search Strategy

Search Implementation:

// Primary search with Eurovision context
String query = "${song.title} ${song.artist} eurovision";
var results = await spotify.searchTracks(query);

// First fallback: without Eurovision context
if (results.isEmpty) {
  query = "${song.title} ${song.artist}";
  results = await spotify.searchTracks(query);
}

// Second fallback: title only
if (results.isEmpty) {
  query = "${song.title}";
  results = await spotify.searchTracks(query);
}

// Handle not found
if (results.isEmpty) {
  return EurovisionTrack.notFound(song);
}

Common Challenges:

  • Alternative versions - The Eurovision version might not be the most popular recording
  • Name variations - Artist names may be spelled differently
  • Missing songs - Some older or obscure Eurovision entries might not be on Spotify
  • Language differences - Songs might be listed under original language titles

22

We Are Developers 2025

Phase 4: Social Sharing

What We're Building

In this phase, we'll add features to share Eurovision coding playlists on social media.

Pick one!

Sharing Service

Platform-specific implementation for Twitter, Instagram, and LinkedIn

Analytics Tracking

Monitor user engagement and sharing patterns

Shareable Cards

Visually appealing playlist cards with Eurovision branding

Copy Options

Text-based sharing and clipboard functionality

23

We Are Developers 2025

Phase 5: Production Polish

What We're Building

In this final phase, we'll add production-quality features and optimizations.

Comprehensive Error Handling

Implement user-friendly error messages for all API failures and edge cases

Loading States

Add progress indicators and skeleton screens for better user experience

Performance Optimization

Implement caching and request batching to improve app responsiveness

Visual Polish

Add final visual touches and animations for a professional look and feel

24

We Are Developers 2025

Error Handling Strategy

GitHub API Failures:

try {
  commits = await githubService.fetchCommits(username);
} catch (e) {
  if (e is RateLimitException) {
    showRateLimitDialog();
  } else if (e is UserNotFoundException) {
    showUserNotFoundMessage();
  } else {
    showGenericErrorMessage();
  }
}

AI API Failures:

try {
  playlist = await aiService.generatePlaylist(commits);
} catch (e) {
  // Fallback to rule-based recommendations
  playlist = sentimentAnalyzer
      .getRecommendations(commits);
  
  // Track failure for analytics
  analytics.trackEvent('ai_failure', {
    'error_type': e.toString(),
    'fallback_used': true
  });
}

25

We Are Developers 2025

What You've Accomplished

Complete Flutter App

Built a production-ready application with multiple API integrations

Major APIs Integrated

GitHub, AI Models, and Spotify working together seamlessly

Countries Represented

All Eurovision participating nations throughout history

Workshop Phases

Completed all development phases from integration to production polish

26

We Are Developers 2025

Next Steps & Resources

Immediate Improvements

  • Implement playlist persistence
  • Add user preferences and favorites
  • Improve AI prompt engineering

Stay Connected

Share your Eurovision coding playlists with #githubcommunity

Documentation

"Every great developer has their soundtrack. Today you discovered yours is Eurovision! 🇪🇺"

Made with