Skip to content

2i2c-org/sync-asana

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sync-asana

Keeps 2i2c's Asana in sync with external sources. Two independent syncs live here:

  1. CSH issue sync — GitHub issues labeled CSH become Asana tasks.
  2. Engagement title sync — Asana projects in the "Active Engagements" portfolio are renamed to match their HubSpot deal names.

Engagement title sync

Each project in the "Active Engagements" Asana portfolio has a HubSpot Deal URL custom field holding a HubSpot deal URL. A daily workflow (sync-project-titles.yml, 11:00 UTC) renames each project to match its HubSpot deal name.

Deal names come from the deals_cleaned sheet of hubspot.xlsx in the hubspot-latest release of 2i2c-org/data-private, which refreshes daily at 09:00 UTC. Projects with an empty or unparseable deal URL, or a deal ID not in the data, are skipped with a warning.

Run it locally:

node --env-file=.env scripts/sync-project-titles.js --dry-run

Required env vars (put them in a .env file):

  • ASANA_ACCESS_TOKEN — Asana personal access token
  • CSH_SYNC_PAT — GitHub token with read access to 2i2c-org/data-private

Config lives in config/asana-config.json under engagements (portfolio_gid comes from the portfolio's URL in the Asana web app). Unit tests (npm test) cover the title-sync helpers only.

CSH issue sync

Automatically creates Asana tasks when a GitHub issue is labeled CSH (Community Success Hours) on any repo in the 2i2c-org organization.

How It Works

  1. A contributor adds the CSH label to a GitHub issue
  2. A GitHub Actions workflow fires on the issue event
  3. The workflow fetches enriched metadata from the issue and its GitHub Project board (via GraphQL)
  4. It creates (or updates) a corresponding Asana task with mapped fields
  5. It comments on the GitHub issue with a link to the new Asana task

A scheduled batch sync (csh-batch-sync.yml, every 15 minutes on weekdays) catches project-board field changes that don't fire issue events.

Repository Structure

sync-asana/                            # This repo (2i2c-org/sync-asana)
├── .github/workflows/
│   ├── csh-sync.yml                   # Reusable workflow (workflow_call)
│   ├── csh-batch-sync.yml             # Scheduled batch sync of CSH issues
│   └── sync-project-titles.yml        # Daily engagement title sync
├── scripts/
│   ├── sync-to-asana.js               # CSH: single-issue webhook entry point
│   ├── sync-all.js                    # CSH: batch entry point
│   ├── sync-issue.js                  # CSH: shared core sync logic
│   ├── github-metadata.js             # CSH: GraphQL queries for board fields
│   ├── field-mapping.js               # CSH: GitHub → Asana field mapping
│   ├── sync-project-titles.js         # HubSpot → Asana project title sync
│   ├── setup-asana.js                 # One-time config discovery/validation
│   ├── asana-client.js                # Asana REST API wrapper (shared)
│   └── __tests__/                     # Unit tests (title-sync helpers)
├── config/
│   ├── asana-config.json              # Asana project/field GIDs
│   └── user-mapping.json              # GitHub login → Asana user GID
└── caller-workflow-template.yml       # Copy into participating repos

Setup

1. Configure Asana

Run the setup script to discover GIDs, validate the Asana project's custom fields, and generate config/asana-config.json:

export ASANA_ACCESS_TOKEN="your-asana-token"
npm run setup                                      # interactive
node scripts/setup-asana.js --project-gid 1234567890  # or direct

The script reports anything you still need to do (missing fields, user mapping, enum mappings).

2. Set organization secrets

In the 2i2c-org organization settings (Settings → Secrets and variables → Actions):

Secret Name Value
ASANA_ACCESS_TOKEN Asana personal access token or service account token
CSH_SYNC_PAT GitHub PAT with repo, project:read scopes (cross-repo GraphQL for the CSH sync; also needs read access to 2i2c-org/data-private for the engagement title sync)

3. Add caller workflows to each repo

In every repo that should participate in CSH sync, copy caller-workflow-template.yml into .github/workflows/. The caller is intentionally minimal — all logic lives in this central repo.

Field Mapping

Fields from the Product and Services board (project #57) and the issue itself map to Asana as follows. A custom field is only synced when its GID is set in config/asana-config.json; unconfigured fields are skipped.

GitHub source Asana target
Issue title Task name
Issue body Task notes (plain text)
Issue assignees Task assignee (via config/user-mapping.json)
Issue URL GitHub Issue URL text field (idempotency key)
Repository full name GitHub Repo text field
Labels (excluding CSH) GitHub Labels text field
Status / Priority / Allocation / Unplanned Same-named single-select fields (via enum_mappings)
Estimate / Hours spent Same-named number fields
Iteration Iteration text field (iteration title)
Start date / End date Native start_on / due_on
Process / SoW Same-named text fields
Milestone due date due_on (fallback)

Idempotency

Before creating a task, the script searches Asana for an existing task whose GitHub Issue URL matches the issue's URL, and updates it instead of creating a duplicate. Re-labeling or re-running the workflow is safe.

About

No description, website, or topics provided.

Resources

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors