Compare commits

..

11 Commits

21 changed files with 960 additions and 776 deletions

View File

@@ -1,83 +1,53 @@
{
"$ref": "#/definitions/posts",
"definitions": {
"posts": {
"type": "object",
"properties": {
"title": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"title": {
"type": "string"
},
"slug": {
"type": "string"
},
"description": {
"type": "string"
},
"added": {
"anyOf": [
{
"type": "string"
},
"slug": {
"type": "string"
},
"description": {
"type": "string"
},
"added": {
"anyOf": [
{
"type": "string"
},
{
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "string",
"format": "date"
},
{
"type": "integer",
"format": "unix-time"
}
]
}
]
},
"updated": {
"anyOf": [
{
"type": "string"
},
{
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "string",
"format": "date"
},
{
"type": "integer",
"format": "unix-time"
}
]
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"$schema": {
"type": "string"
{
"type": "string",
"format": "date-time"
}
},
"required": [
"title",
"slug",
"description",
"added",
"tags"
],
"additionalProperties": false
]
},
"updated": {
"anyOf": [
{
"type": "string"
},
{
"type": "string",
"format": "date-time"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"$schema": {
"type": "string"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
"required": [
"title",
"slug",
"description",
"added",
"tags"
]
}

View File

@@ -1,4 +1,6 @@
import __ASTRO_IMAGE_IMPORT_17cH5r from "../assets/dyndns-kaxeroa/dyndns-kaxeroa.svg?astroContentImageFlag=&importer=posts%2Fdyndns-kaxeroa.md";
export default new Map([["../assets/dyndns-kaxeroa/dyndns-kaxeroa.svg?astroContentImageFlag=&importer=posts%2Fdyndns-kaxeroa.md", __ASTRO_IMAGE_IMPORT_17cH5r]]);
import __ASTRO_IMAGE_IMPORT_Z84Mlf from "../assets/enfoque-pragmatico-test/marrazkia.jpg?astroContentImageFlag=&importer=posts%2Fun-enfoque-pragmatico-de-nuestros-tests-del-frontend.md";
import __ASTRO_IMAGE_IMPORT_28bbst from "../assets/hay-algo-de-negocio-en-tu-codigo/arrival.jpg?astroContentImageFlag=&importer=posts%2Fhay-algo-de-negocio-en-tu-codigo.md";
export default new Map([["../assets/dyndns-kaxeroa/dyndns-kaxeroa.svg?astroContentImageFlag=&importer=posts%2Fdyndns-kaxeroa.md", __ASTRO_IMAGE_IMPORT_17cH5r], ["../assets/enfoque-pragmatico-test/marrazkia.jpg?astroContentImageFlag=&importer=posts%2Fun-enfoque-pragmatico-de-nuestros-tests-del-frontend.md", __ASTRO_IMAGE_IMPORT_Z84Mlf], ["../assets/hay-algo-de-negocio-en-tu-codigo/arrival.jpg?astroContentImageFlag=&importer=posts%2Fhay-algo-de-negocio-en-tu-codigo.md", __ASTRO_IMAGE_IMPORT_28bbst]]);

112
.astro/content.d.ts vendored
View File

@@ -15,21 +15,13 @@ declare module 'astro:content' {
[key: string]: unknown;
};
}
}
declare module 'astro:content' {
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
export type CollectionKey = keyof AnyEntryMap;
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
export type ContentCollectionKey = keyof ContentEntryMap;
export type DataCollectionKey = keyof DataEntryMap;
export type CollectionKey = keyof DataEntryMap;
export type CollectionEntry<C extends CollectionKey> = Flatten<DataEntryMap[C]>;
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
ContentEntryMap[C]
>['slug'];
export type ReferenceDataEntry<
C extends CollectionKey,
@@ -38,41 +30,17 @@ declare module 'astro:content' {
collection: C;
id: E;
};
export type ReferenceContentEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}) = string,
> = {
collection: C;
slug: E;
};
export type ReferenceLiveEntry<C extends keyof LiveContentConfig['collections']> = {
collection: C;
id: string;
};
/** @deprecated Use `getEntry` instead. */
export function getEntryBySlug<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
// Note that this has to accept a regular string too, for SSR
entrySlug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
/** @deprecated Use `getEntry` instead. */
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
collection: C,
entryId: E,
): Promise<CollectionEntry<C>>;
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
export function getCollection<C extends keyof DataEntryMap, E extends CollectionEntry<C>>(
collection: C,
filter?: (entry: CollectionEntry<C>) => entry is E,
): Promise<E[]>;
export function getCollection<C extends keyof AnyEntryMap>(
export function getCollection<C extends keyof DataEntryMap>(
collection: C,
filter?: (entry: CollectionEntry<C>) => unknown,
): Promise<CollectionEntry<C>[]>;
@@ -84,14 +52,6 @@ declare module 'astro:content' {
import('astro').LiveDataCollectionResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>
>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
entry: ReferenceContentEntry<C, E>,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
@@ -100,15 +60,6 @@ declare module 'astro:content' {
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
slug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
@@ -126,40 +77,47 @@ declare module 'astro:content' {
): Promise<import('astro').LiveDataEntryResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>>;
/** Resolve an array of entry references from the same collection */
export function getEntries<C extends keyof ContentEntryMap>(
entries: ReferenceContentEntry<C, ValidContentEntrySlug<C>>[],
): Promise<CollectionEntry<C>[]>;
export function getEntries<C extends keyof DataEntryMap>(
entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
): Promise<CollectionEntry<C>[]>;
export function render<C extends keyof AnyEntryMap>(
entry: AnyEntryMap[C][string],
export function render<C extends keyof DataEntryMap>(
entry: DataEntryMap[C][string],
): Promise<RenderResult>;
export function reference<C extends keyof AnyEntryMap>(
export function reference<
C extends
| keyof DataEntryMap
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
// Invalid collection names will be caught at build time.
| (string & {}),
>(
collection: C,
): import('astro/zod').ZodEffects<
): import('astro/zod').ZodPipe<
import('astro/zod').ZodString,
C extends keyof ContentEntryMap
? ReferenceContentEntry<C, ValidContentEntrySlug<C>>
: ReferenceDataEntry<C, keyof DataEntryMap[C]>
import('astro/zod').ZodTransform<
C extends keyof DataEntryMap
? {
collection: C;
id: string;
}
: never,
string
>
>;
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
// Invalid collection names will be caught at build time.
export function reference<C extends string>(
collection: C,
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
type InferEntrySchema<C extends keyof DataEntryMap> = import('astro/zod').infer<
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
>;
type ContentEntryMap = {
};
type ExtractLoaderConfig<T> = T extends { loader: infer L } ? L : never;
type InferLoaderSchema<
C extends keyof DataEntryMap,
L = ExtractLoaderConfig<ContentConfig['collections'][C]>,
> = L extends { schema: import('astro/zod').ZodSchema }
? import('astro/zod').infer<L['schema']>
: any;
type DataEntryMap = {
"posts": Record<string, {
@@ -173,8 +131,6 @@ declare module 'astro:content' {
};
type AnyEntryMap = ContentEntryMap & DataEntryMap;
type ExtractLoaderTypes<T> = T extends import('astro/loaders').LiveLoader<
infer TData,
infer TEntryFilter,
@@ -183,10 +139,10 @@ declare module 'astro:content' {
>
? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError }
: { data: never; entryFilter: never; collectionFilter: never; error: never };
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
LiveContentConfig['collections'][C]['schema'] extends undefined

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
{
"_variables": {
"lastUpdateCheck": 1769022540618
"lastUpdateCheck": 1780302068706
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

View File

@@ -9,9 +9,9 @@
"astro": "astro"
},
"devDependencies": {
"@astrojs/rss": "^4.0.15",
"@astrojs/sitemap": "^3.7.0",
"astro": "^5.16.13",
"@astrojs/rss": "^4.0.18",
"@astrojs/sitemap": "^3.7.3",
"astro": "^6.4.2",
"prettier": "^3.8.1",
"prettier-plugin-astro": "^0.14.1"
},

1138
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,6 @@
allowBuilds:
esbuild: true
sharp: true
onlyBuiltDependencies:
- esbuild
- sharp

View File

@@ -0,0 +1,39 @@
---
title: The Beatles taldearen diskografia bisitatzen
slug: beatles-diskografia
description: >-
Errepaso bat The Beatles taldearen diskografiari.
tags:
- musika
added: "2026-4-16"
---
Los Delinqüentes taldeko Diego Pozo gitar-joleari [egindako elkarrizketa batean](https://www.youtube.com/watch?v=30OMn_OZN28), galdetzen zioten ea zein ziren taldearen erreferenteak. Bere erantzuna: diska bat sortzen ari zirela blokeo batera iristen zirenean, Migué, Canijo eta hirurok, The Beatles taldearen diska bat jartzen zuten. "Zigarro" bat egin eta, ixiltasunean, diskoa osorik entzuten zutela. Batzuetan, Migué-k, negar batean, diska kentzeko eskatzen zuela. Bestalde, Laban egindako "Hasiera bat" diskaren aurkezpenean, Gorka Urbizuk, diskaren sorrera prozesuan egunero The Beatles entzuten pasiran ateratzen zela kontatu zigun. Hortik denbora batera, Abbey Road estudio mitikoan single batzuk grabatu zituen.
Ez dakit zer duen The Beatles taldeak. Tira, jakin badakit, talde ikonikoa izan zela: John Lenon, Paul McCartney, Yellow Submarine... Baina, telebista edota irratian entzundako kanta mitikoetaz gain, ez diot inoiz gehiegi erreparatu talde horri. Bada, egoerari buelta ematea erabaki dut eta, hurrengo egunetan, bere diskografia osorik entzutea otu zait.
# Diskografia entzuteko ordena
Ez nekien oso ongi nondik hasi bidai hau. Interneten arakatuta, Reddit-en pertsona batek zalantza bera planteatzen zuela ikusi nuen eta [erantzun honekin geratu naiz](https://www.reddit.com/r/beatles/comments/1i9twf/comment/cb2xzev/):
> Listen to them chronologically, excluding Yellow Submarine, switching Abbey Road and Let It Be, and swapping out Let It Be for the superior Naked version. After that, listen through Past Master for their non-album singles and finally finish it all of with a listen to Love.
Bereziki interesgarria iruditzen zait taldearen eboluzioa ikustea. Gauzak horrela eta interneteko pertsona ezezagun horren jakituriari jarraituz, hau da jarraitutako ordena:
1. Please Please Me
2. With The Beatles
3. A Hard Days Night
4. Beatles For Sale
5. Help!
6. Rubber Soul
7. Revolver
8. Sgt. Peppers Lonely Hearts Club Band
9. The Beatles (White Album)
10. Let It Be... Naked
11. Abbey Road
12. Past Masters
13. Love
## Alternatiba irisgarriago bat
Reddit-en aurkitutako beste erabiltzaile batek, alternatiba bezala, [abiapuntu bezala One bilduma diska erabiltzea planteatzen du](https://www.reddit.com/r/beatles/comments/t9r40x/my_recommended_order_of_first_listening_to/). Hortik, gustokoen zaizkigun etapa edota kantei tiraka, The Beatles-en disketan murgiltzea planteatzen du. Nik bide "luzea" jarraitzea erabaki dudan arren, ibilbide-orri interesgarria iruditzen zait nekatzen banaiz jarraitzeko.

View File

@@ -0,0 +1,39 @@
---
title: "Hay algo de negocio en tu código: (algunas) ideas para la entrega de valor"
slug: hay-algo-de-negocio-en-tu-codigo
description: >-
Biko2 enpresako blogean idatzitako artikulu bat.
tags:
- biko2egunak
added: "2019-11-19"
---
*_Oharra: Honako hau, Biko2 enpresan lan egiten nuenean haien blogean idatzitako artikulu bat da. [Iturria (funtzionatzen duen arte)](https://blog.biko2.com/actualidad-biko/hay-algo-de-negocio-en-tu-codigo-algunas-ideas-para-la-entrega-de-valor/)._*
---
![Shaun Tan ilustratzailearen "The Arrival" liburuan oinarritutako nik egindako marrazki bat. Eraikin handi batzuk ikusten dira eta, behean, familia bat (aita, ama eta alaba) kale erdian. Eraikinen artean, olagarroen tentakulo batzuk daude.](../assets/hay-algo-de-negocio-en-tu-codigo/arrival.jpg)
Es sábado por la mañana y Miren, frontend developer, entra a clase en nuestro Curso de Desarrollo de Software. El plan del día no es el esperado en un curso que promete ser técnico: Rubén y yo dinamizaremos una sesión sobre definición de historias de usuario. Como es habitual en la Biko School, abrimos boca con una introducción teórica para, acto seguido, poner en práctica lo aprendido.
Empezamos explicando que, para hacer bien nuestro trabajo, es fundamental un profundo conocimiento del negocio. En vez de limitarnos a ejecutar una solución, debemos participar en la definición de esta. Para ello, es necesaria una conversación entre las personas implicadas en el proyecto, desde perfiles de negocio hasta perfiles de desarrollo. Una conversación que se da en el dominio del problema, ahí donde solo se habla de las necesidades de la persona que utiliza nuestro software. Una vez entendidas estas necesidades es cuando pasamos al dominio de la solución, donde se definen y dibujan formularios, tablas y llamadas al API.
Esta conversación sobre las necesidades debe estar exenta de ambigüedades. Tenemos que huir de sinónimos, jergas y motes. El «bueno, ya me has entendido» no nos vale. Si surge un concepto de negocio, consensuamos una definición para este. Si surge una nueva palabra para referirnos a ese concepto de negocio, la descartamos o sustituimos la que teníamos. Nunca utilizamos la misma palabra para dos conceptos, ni dos palabras para un mismo concepto. De esta manera propiciamos el lenguaje ubicuo, pilar en el desarrollo de software.
¿Cuántas veces has visto parar un desarrollo por no tener claro qué ocurre en un escenario concreto? ¿Cuántas mañanas has perdido entre emails, llamadas y chats para aclarar una duda? ¿Te ha tocado ejercer de aguafiestas al tener que decir que un diseño es demasiado costoso (si no imposible) de implementar? ¿Has ejecutado una solución creyendo que podía haber sido mejor, sin tener posibilidad de cambiarla? Miren hace un gesto de complicidad. Lo ha vivido, ha estado ahí. Lo ha sufrido.
Aquello que Miren ha sufrido tiene nombre: aprendizaje accidental. El aprendizaje accidental es aquel que ocurre sin esperarlo, cuando todo debería estar claro. Nos frena, nos hace ser ineficientes y genera frustración en el equipo. Contra el aprendizaje accidental tenemos el aprendizaje deliberado, aquel que ocurre cuando todas las personas implicadas en el proyecto se alinean para entender cuál es la necesidad que se quiere cubrir. Solo así podemos sacar partido al verdadero potencial del equipo. Solo así podremos centrarnos en la entrega de valor.
El tiempo avanza, las transparencias se terminan y toca ponerse manos a la obra. Antes de eso, queda ver cómo llevar a la práctica estos principios de los que hemos hablado. Explicamos que, en uno de nuestros proyectos en Biko, nos está funcionando el enfoque [Specification by Example](https://en.wikipedia.org/wiki/Specification_by_example#:~:text=Specification%20by%20example%20(SBE)%20is,examples%20instead%20of%20abstract%20statements.) que llevamos a cabo en talleres de Example Mapping. Explicamos en qué consisten (nota del autor: daría para otro post).
Arrancamos la práctica: Miren y su equipo harán un taller de Example Mapping para una aplicación en la que Rubén y yo asumimos el rol de negocio. No olvidemos los principios de los que hemos hablado: dominio del problema, evitar las ambigüedades y aprendizaje deliberado. Miren los tiene apuntados en su cuaderno, empiezan las conversaciones.
Durante el ejercicio, ocurre algo que Rubén y yo no esperamos. En el taller, el equipo de Miren descubre que nuestro planteamiento permite a algunas personas generar gastos de miles de euros. La idea con la que veníamos no solo no es la mejor posible, sino que puede hundirnos. Menos mal que Miren ha sabido evitarlo, proponiendo una nueva regla que hará que esto no ocurra. Como negocio nos parece bien, muchas gracias y adelante, buen trabajo.
Miren todavía no ha encendido su portátil. En ese momento entiende que, con un bolígrafo y un papel, ha aportado más valor del que hubiera aportado en mil líneas de código. Descubre que, su perfil de frontend developer, va mucho más allá de ejecutar una solución, de implementar un diseño. Su trabajo no es el código, el código es un resultado de su trabajo. Su responsabilidad es entender el negocio y hacerlo suyo.
Nosotros también nos llevamos una lección. Han pillado a Rubén y Aitor, ¿cómo puede ser? Bueno, no pasa nada, siempre podemos darle una vuelta para futuras ediciones del curso. Aunque, pensándolo mejor, creo que está bien así.
## Si quieres profundizar en el tema
Puedes [buscarme en Twitter](https://twitter.com/aitorcurrutia) o [buscar a Rubén](https://twitter.com/rubenbpv), gran conocedor de este enfoque. También te recomiendo [el libro «The BDD Books - Discovery» escrito por Gáspár Nagy y Seb Rose](https://leanpub.com/bddbooks-discovery). Lectura interesante, llena de ejemplos prácticos y anécdotas vividas por los autores.

View File

@@ -0,0 +1,22 @@
---
title: Lorategi digitalak
slug: lorategi-digitalak
description: >-
Nire lorategi digitalei buruzko ikuspegia.
tags:
- pertsonala
added: "2026-1-24"
---
Lorategi digital guztiek daukate lorategi digitalei buruzko sarrera bat. Lorategiaren analogiari jarraituz, esan daiteke sarrera hau belarra dela. Edo lurra, batzuetan emankorra, bestetan antzua, baina ezinbestekoa. Nik neuk mugimendu honi buruzko apunte batzuk jarri nahiko nituzke, inspiragarria suertatzen zaidalako eta honen parte izan nahi dudalako.
Lorategi digitalen testuinguru bat emateko, oso interesgarria da [Maggie Appletonek idatzitako artikulu hau](https://maggieappleton.com/garden-history). Funtsean, lorategi digital bat gure mobidak interneten jartzeko modu bat da. Blog baten antza du, baina hauekin duen ezberdintasun nagusia kaosa eta fintze faltan dago. Ideia da apunteak botatzen joatea (ereitea) eta, nahi dugun heinean, hauetara bueltatzea eta lantzen joatea. Algoritmoen eta biralizazioaren garaiari erantzun bat bezala ulertu daiteke.
## Bidean aurkitutako hainbat lorategi digital
Hauek dira niretzat inspiragarri diren lorategi digital batzuk:
- [Maggie Appleton](https://maggieappleton.com)
- [Heydon Pickering](https://heydonworks.com/)
- [Cassidy Williams](https://cassidoo.co/)
- [Karlos G. Liberal (patxangas)](https://www.karlosgliberal.com/)

15
posts/mamihlapinatapai.md Normal file
View File

@@ -0,0 +1,15 @@
---
title: Mamihlapinatapai
slug: mamihlapinatapai
description: >-
Yagan hizkuntzako hitz honek hainbat sekretu gordetzen ditu.
tags:
- pertsonala
added: "2026-1-24"
---
`Mamihlapinatapai` hitza, Suaren lurraldeko uharteetako [Yagan hizkuntzako](https://eu.wikipedia.org/wiki/Yagan_hizkuntza) hitz bat da. Berezitasun bat du, izan ere, Guiness munduko errekorren liburuan azaltzen da. Munduko hitzik laburrena da. Hau da, gutxirekin gehien esaten duena. Itzultzen oso zaila omen da, baina ni, itzultzailea ez naizen arren, [gaztelerako Wikipediatik](https://es.wikipedia.org/wiki/Mamihlapinatapai) itzultzen saiatuko naiz:
> Bi pertsonen arteko begirada, bakoitzak espero duenean besteak biek nahi duten ekintza bat hastea, baina bietako inor hastera animatzen ez denean.
2022ko otsailaren 16an hil zen, 93 urterekin, [Cristina Calderón](https://eu.wikipedia.org/wiki/Cristina_Calder%C3%B3n). Hau izan da Yagan hizkuntzak izan duen azken hiztuna. Bere ahizpa Ursula 2003an hil zenetik, ez zuen norekin hizkuntza horretan hitz egin. Ezin zion inori mamihlapinatapai esan, berarengandik kilometro batzuetara Emelinda Acuñak ere hitz egiten zuen arren. Edonola ere, Emelinda 2012an zendu zen eta, 2022 arte, Cristina izan zen hiztun bakarra.

122
posts/pi-hole-pivpn copy.md Normal file
View File

@@ -0,0 +1,122 @@
---
title: "Cisco CCNA-1: Praktikarako apunteak"
slug: cisco-ccna-1-praktika-apunteak
description: >-
Cisco CCNA-1 egin ondoren, praktikarako apunte nagusiak jasotzen ditut.
tags:
- katxarreoa
added: "2026-6-1"
---
Laneko kontuak direla eta, [Cisco CCNA-1](https://www.netacad.com/es/courses/ccna-introduction-networks?courseLang=en-US) ziurtagiria atera nuen. Bi zati ditu: test teoriko bat eta Packet Tracer simulatzaileko praktika bat. Hemen, simulatzailean erabilitako komando nagusiak jasoko ditut.
# Gailuen konfigurazio orokorrak
## Hasierako konfigurazioak
- Gailuak ezezagun zaizkion komandoak interneten bilatzea ekiditea.
- Host izen bat ezartzea.
- Hasierarako mezu bat erakustea.
```
no ip domain-lookup
hostname X
banner motd #Unauthorized access to this device is prohibited!#
```
## Pasahitzak
- Pasahitza ezartzea konfiguraziora sartzeko.
- Pasahitzak enkriptatuta gordetzea.
- Pasahitzek gutxienez 10 karaktere izateko araua ezartzea.
```
enable secret ZurePasahitza
service password-encryption
security passwords min-length 10
```
## SSH-a konfiguratzeko
- Domeinu izena ezarri, RSA gakoak sortu ahal izateko.
- Erabiltzaile/pasahitz bat sortu.
- VTY (Virtual Teletype) linea guztiak (16 dira) konfiguratu:
- SSH-a besterik ez onartu (telnet ezgaitu).
- Datubase lokaleko erabiltzaileak erabili (gure kasuan, netadmin).
- RSA gakoak sortu 1024 biteko luzerarekin.
```
ip domain-name netsec.com
username netadmin secret netadminPasahitza
line vty 0 15
transport input ssh
login local
exit
crypto key generate rsa
1024
```
## Kontsolari pasahitza ezarri
- Pasahitza konfiguratu.
- Autentikatzeko pasahitza eskatzera behartu (`login`).
```
line console 0
password Pasahitza
login
exit
```
## Konfigurazioa kontsolidatu
```
copy running-config startup-config
```
# Router-aren konfigurazioa
## Interfazeen konfigurazioa
Interfaze bakoitzarekin:
- Deskribapena sortu.
- IP helbide eta maskara konfiguratu.
- Interfazea piztu.
```
interface g0/0/0
description Connect to Subnet B
ip address <ip-helbidea> <maskara>
no shutdown
exit
```
# Switch-aren konfigurazioa
## 1. VLAN-erako SVI (Switch Virtual Interfaze) interfazea konfiguratu
- Deskribapena sortu.
- IP helbidea eta maskara konfiguratu.
- SVI piztu.
- Atebiderako IP helbidea konfiguratu.
```
interface vlan 1
description Switch Subnet A
ip address <ip-helbidea> <maskara>
no shutdown
exit
ip default-gateway <atebiderako-ip-helbidea>
```
## Erabiltzen ez diren portuak itzali
```
int range f0/1 - 4, f0/7 - 24, g0/1 - 2
description Unused switch ports
shutdown
end
```

View File

@@ -0,0 +1,31 @@
---
title: Bideojokoak Raspberry Pi batean
slug: raspberry-pi-emulazioa
description: >-
Nola erabili Raspberry Pi gailu bat bideojokoak emulatzeko.
tags:
- katxarreoa
added: "2026-1-25"
---
_Oharra: WIP bat da hau, oso berde dago._
---
Bikotea eta biok pote bat hartzen ari ginela, bigarren eskuko denda baten lehioan gelditu ginen. Bertan, hainbat bideo-kontsola "retro" zeuden salgai. Fantaseatzen hasi ginen, zeinen dibertigarria izango zen gaztetako bideojokoetara jostatzea. Etxeko kajoi batean _Raspberry Pi Model 3B+_ bat neukanez, emuladore bat instalatzea otu zitzaigun.
## Raspberry Pi-rako emuladoreak
"Bitxeatzen" hasi nintzenean, Raspberry Pi-an aintzinako bideojokoetara jolasteko ekosistema oparoa dagoela ikusi nuen. Polita da hau ikustea, baina, zer aukeratu? Ikusi nuenetik, hauek izan ziren, niretzat, aukerarik aipagarrienak.
### RetroPie
[RetroPie](https://retropie.org.uk/) izan zen nire lehen aukera, izan ere, hau zen ezagutzen nuen bakarra. Uste dut proiektu hau aitzindari izan dela kontu honekin eta, aspaldi, lankide batzuengandik izan nuen honen berri. Arazo handi bat du: 2022tik ez dela eguneratu.
### Batocera
[Batocera](https://batocera.org/) jokoen emulaziora bideratutako Linux distribuzio bat da. Nahikotxo eguneratzen da, interfaze ederra du eta oso erabilia da. Azkenean, hau da aukeratutako distribuzioa.
## ROM-ak eskuratzeko
- [/r/roms Megathread](https://r-roms.github.io/)

View File

@@ -0,0 +1,27 @@
---
title: Sobre developers y (buenas) personas
slug: sobre-developers-y-buenas-personas
description: >-
Biko2 enpresako blogean idatzitako artikulu bat.
tags:
- biko2egunak
added: "2020-2-18"
---
*_Oharra: Honako hau, Biko2 enpresan lan egiten nuenean haien blogean idatzitako artikulu bat da. [Iturria (funtzionatzen duen arte)](https://blog.biko2.com/actualidad-biko/sobre-developers-y-buenas-personas/)._*
---
Durante el proceso de selección de Biko, entre los nervios e incertidumbre que caracterizan una entrevista de trabajo, alguien me preguntó: «¿Cuál es el mayor reto al que te has enfrentado en tu carrera?» Buena pregunta, aunque me pilló por sorpresa. No recuerdo bien qué contesté, además de balbucear una lista de funcionalidades, tecnologías e infraestructuras con las que había trabajado hasta esa fecha.
Pese a todo, pasé el proceso de selección. Entré en un proyecto interesante, ilusionado por las aventuras que me esperaban. Iba aterrizando, conociendo al equipo, familiarizándome con el negocio y la tecnología. Poco a poco cogía soltura y llegó el momento de asumir el que para mí prometía ser el mayor reto: buscar la manera de hacer testing en el proyecto.
Algunas personas del equipo acordamos que dedicaría un tiempo a analizar cómo lo haríamos. Empecé a entender la teoría: preguntaba a gente, leía libros, buscaba vídeos… Me iba empapando. Compartía con el equipo, pero había gente que no me seguía, sentía que no mostraba interés. ¿Acaso no entendían la importancia del testing? Mi frustración crecía y empecé a bombardear al equipo con recursos sobre el tema. No importaba si los leían, tampoco preguntaba, había que «motivar a la gente». Creía que ayudaba cuando, en realidad, solo presionaba a personas que tenían otras inquietudes en ese momento.
Llegó el momento de saltar del plano teórico al práctico. Entendí la tecnología y herramientas necesarias, buscando la configuración para aplicarlas a nuestro proyecto. Con ayuda, conseguimos montar la infraestructura adecuada. Ahí estaba, era una realidad, podíamos hacer tests en el proyecto. Pero había gente que no los hacía y seguía sin entender qué pasaba. ¿No veían el esfuerzo que había hecho? Lo tenían todo a favor y había gente que no metía un test. En mi afán por aplicar las buenas prácticas que leía en los libros (y buscando un reconocimiento) aumentaba la crispación dentro del equipo y me distanciaba de él.
Algunas personas del equipo estaban motivadas y, poco a poco, iba subiendo el número de tests. Había gente que sentía que se quedaba atrás, pero con ver crecer ese número me bastaba. Cada nuevo test era un logro, me jactaba de tirar del carro y ser un líder. Yo seguía sin escuchar, empujando, mejorando el proyecto a toda costa, presionando al equipo. No entendía que mi tarea era estar al servicio de las necesidades del resto, respetando la diversidad dentro del equipo.
Tengo suerte de formar parte de un gran equipo que, gracias a la atención a la mejora continua, supo pararme los pies. Una persona me dijo algo que me apunté: «En desarrollo de software el reto no es la tecnología, sino las personas». Cientos de tests más tarde lo veo claro: el código lo aguanta todo, basta con meterle horas, probar, fallar y volver a empezar. Las personas no, las personas merecen atención, respeto y cariño.
Si hoy me peguntaran: «¿Cuál es el mayor reto al que te has enfrentado en tu trabajo?» No dudaría, aunque igual sorprendería con una respuesta nada técnica. No hablaría de proyectos, funcionalidades o infraestructuras. Hablaría de la vez que descubrí que esto va de personas y, para mejorar como developer, se empieza por mejorar como compañero. De nada valen las buenas prácticas si no hay empatía, entendimiento y respeto a la diversidad. Contaría ese momento en el que vi que, el equipo que trabaja bien, es el que trabaja feliz. Diría que mi mayor reto fue descubrir todo esto, aunque tenga toda la vida para resolverlo.

View File

@@ -0,0 +1,44 @@
---
title: Un enfoque pragmático de nuestros test del frontend
slug: un-enfoque-pragmatico-de-nuestros-tests-del-frontend
description: >-
Biko2 enpresako blogean idatzitako artikulu bat.
tags:
- biko2egunak
added: "2020-6-10"
---
*_Oharra: Honako hau, Biko2 enpresan lan egiten nuenean haien blogean idatzitako artikulu bat da. [Iturria (funtzionatzen duen arte)](https://blog.biko2.com/actualidad-biko/un-enfoque-pragmatico-de-nuestros-tests-del-frontend/)._*
---
![Nik egindako marrazki bat. Eraikin bat atzean ikusten dela, bambuzko andamio batzuen detallea dago.](../assets/enfoque-pragmatico-test/marrazkia.jpg)
Resulta difícil decir nada que no se haya dicho ya en torno a los beneficios del testing. En Biko, tenemos un compromiso con las buenas prácticas y tenemos clara la responsabilidad de testar nuestras aplicaciones. En este post no vengo a decirte [por qué debes hacer test](https://www.youtube.com/watch?v=vlorWIlPgY0&t), vengo a hablar del enfoque que estamos dando a nuestros test en los desarrollos frontend.
Como software crafters, nuestro oficio es solucionar problemas. No nos limitamos a ejecutar soluciones, entendemos y hacemos nuestro el dominio del problema de negocio que se quiere afrontar. Participamos de forma proactiva en el análisis y diseño de funcionalidades, siempre con un compromiso claro por la entrega de valor.
Como software crafters, en nuestro afán por crear código mantenible, tenemos la responsabilidad de volcar en nuestra base de código todo ese conocimiento que hemos adquirido. No nos limitamos a implementar interfaces, ni nos limitamos a implementar llamadas a un API. Buscamos expresar la intención y motivación que subyace a aquellas soluciones de interfaz que estamos implementando. Aquí es donde iniciamos ese proceso creativo en el que, utilizando el código como materia, vamos moldeando todo aquel conocimiento que tenemos sobre el negocio.
El testing no está exento de este principio: debe estar basado en nuestro conocimiento del negocio. Cuando hacemos un test del frontend, debemos ser capaces de simular la interacción de la persona al otro lado de la aplicación, expresando su intención y motivación. Debemos hablar el lenguaje de nuestro negocio. No nos limitamos a comprobar que ese input recibe ocho dígitos y una letra, comprobamos que una usuaria introduce su DNI para emitir facturas. No comprobamos que recibimos un dato del API, comprobamos que un usuario consulta los siniestros de su póliza.
Para alcanzar este objetivo, es fundamental que nuestros test cubran la interacción con la interfaz de usuario. De nada sirve hacer test unitarios de las capas de nuestra aplicación si no somos capaces de hacer click en el mismo botón que verá la persona que la utilice. A esta persona no le importan nuestros repositorios, servicios de dominio o servicios de aplicación. Esta persona lo único que verá serán botones, campos de formularios o tablas. Si no somos capaces de cubrir esto, estaremos perdiendo una parte importante del potencial de nuestros test.
## Entendido, pero... ¿Cómo lo conseguimos?
En Biko desarrollamos nuestros proyectos frontend (principalmente) en TypeScript y React, utilizando Jest como framework de test. Este framework nos facilita testar todo nuestro core, pero está limitado a la hora de hacer test de nuestras vistas (algo que, como se ha dicho antes, resulta fundamental en un proyecto front). Aquí es donde entra en juego la herramienta React Testing Library.
React Testing Library es una librería de utilidades que extiende de DOM Testing Library y nos permite renderizar una interfaz de usuario para interactuar con el DOM. Se basa en un principio: «cuanto más se parezcan tus test a cómo se usa tu software, más confianza te darán». Cuando lo lees parece obvio, pero es un salto cualitativo en el enfoque que damos a los test de nuestra interfaz. No testamos detalles de implementación de nuestros componentes, sino que actuamos directamente sobre el DOM, del mismo modo que lo hará quien use nuestro software.
Utilizando esta librería junto a Jest, tenemos la capacidad de hacer test de nuestras vistas de forma agnóstica a la implementación. Mockeando los colaboradores como en cualquier pieza de nuestra aplicación, buscamos elementos del DOM (por texto o label, igual que lo haría cualquiera que navegue la web) e interactuamos con ellos comprobando que la respuesta obtenida es la adecuada. Esto nos permite cubrir con test las reglas de negocio en la capa de entrega e incluso, por qué no, desarrollar interfaces de usuario mediante TDD.
## En conclusión
React Testing Library aumenta de forma considerable la fiabilidad de nuestros test del frontend. Nos permite abstraernos de los detalles de implementación y tener unos test lo más parecido posibles a la manera en la que se utilizará nuestro software. Gracias a este principio, obtenemos una batería de test más robusta y que expresa más intención. Esto último nos lleva a un código más mantenible y, como software crafters, pocas cosas nos hacen más felices que una base de código mantenible.
## Si quieres saber más
Si quieres seguir investigando, añado un vídeo y un artículo que pueden resultarte interesantes. Además, si tienes inquietudes sobre testing, buenas prácticas y entrega de valor, siempre puedes buscarnos en redes sociales (a Biko o a mí mismo), nos encantará conocerte.
- Un vídeo: [The Pragmatic Frontend Tester](https://www.youtube.com/watch?v=XjFeUUZm50g) ([Adriá Fontcuberta](https://twitter.com/afontq))
- Un artículo: [No pierdas el tiempo escribiendo tests](https://blog.koalite.com/2017/11/no-pierdas-el-tiempo-escribiendo-tests/) ([Juan María Hernández](https://twitter.com/gulnor))

View File

@@ -7,7 +7,7 @@ const today = new Date();
<footer>
<div>
{today.getFullYear()} aitor c. urrutia aranburu · <a
href="https://github.com/txarli/txarli.dev">blog honen kodea irekia da</a
href="https://git.fosil.eu/txarli/txarli.dev">blog honen kodea irekia da</a
>! 🖤
</div>

View File

@@ -15,7 +15,6 @@ import { SITE_TITLE, SITE_DESCRIPTION } from "../config";
<HeaderLink href="/">hasiera</HeaderLink>
<HeaderLink href="/post">postak</HeaderLink>
<HeaderLink href="https://sayagata.txarli.dev">sayagata</HeaderLink>
<HeaderLink href="https://github.com/txarli">github</HeaderLink>
<HeaderLink href="https://mastodon.eus/@txarli" rel="me">mastodon</HeaderLink>
</nav>
<style>

View File

@@ -124,16 +124,11 @@ header {
}
a {
display: inline-block;
color: var(--black);
text-decoration-thickness: 0.3ex;
text-underline-offset: 0.3ex;
}
a:hover {
transform: translate(-4px, -4px);
}
nav {
position: sticky;
top: 0;